问题描述
我一直在研究这个问题,尽管我找到了信息,但似乎有些细节我没有掌握。我想将信息从 Activity 传递到已经附加的 Fragment。这是当前代码:
SearchActivity.java
public class SearchActivity extends AppCompatActivity {
private static final int FRAG_USERS = 0;
private static final int FRAG_MESSAGES = 1;
private int currentFrag = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
setupActionBar();
setupViewPager();
}
private void setupActionBar() {
ActionBar actionBar = this.getSupportActionBar();
actionBar.setTitle("");
actionBar.setDisplayHomeAsUpEnabled(true);
}
private void setupViewPager() {
ViewPager2 searchVP2 = findViewById(R.id.searchVP2);
searchVP2.setAdapter(new SearchPagerAdapter(this));
TabLayout searchTL = findViewById(R.id.searchTL);
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(searchTL,searchVP2,(tab,position) -> {
switch (position) {
case 0: {
tab.setText(R.string.users);
break;
} case 1: {
tab.setText(R.string.messages);
break;
}
}
});
tabLayoutMediator.attach();
searchTL.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
currentFrag = searchTL.getSelectedTabPosition();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) { }
@Override
public void onTabReselected(TabLayout.Tab tab) { }
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_searchable,menu);
SearchView searchView = (SearchView) menu.findItem(R.id.searchIT).getActionView();
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setIconified(false);
searchView.setFocusable(true);
searchView.requestFocusFromTouch();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String query) {
if (!TextUtils.isEmpty(query)) {
if (currentFrag == FRAG_USERS) {
Bundle bundle = new Bundle();
bundle.putString(Constants.BUNDLE_SEARCH,query);
new SearchUserFragment().setArguments(bundle);
//SearchUserFragment.newInstance(query);
} else {
SearchMessageFragment.newInstance(query);
}
}
return true;
}
});
return true;
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}
SearchUserFragment.java(消息片段在这方面是一样的)
public class SearchUserFragment extends Fragment {
private TextView notFoundTV;
private RecyclerView searchUserRV;
private MaterialCardView searchTipCV;
private Map<String,User> userMap;
@Override
public View onCreateView(@NonNull LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_search_message,container,false);
notFoundTV = view.findViewById(R.id.notFoundTV);
searchTipCV = view.findViewById(R.id.searchTipCV);
refreshRV(view);
return view;
}
private void refreshRV(View view) {
userMap = new HashMap<>();
searchUserRV = view.findViewById(R.id.searchMessageRV);
searchUserRV.setHasFixedSize(true);
searchUserRV.setLayoutManager(new LinearLayoutManager(getContext()));
}
public void searchUser(String query) {
userMap.clear();
boolean isUserNameValid = true;
String finalQuery = query.trim();
if (finalQuery.isEmpty()) {
setViewsVisibility(View.GONE,View.VISIBLE,View.GONE);
isUserNameValid = false;
} else if (finalQuery.length() < 4 || !finalQuery.matches("^[a-zA-Z0-9]+$")) {
setViewsVisibility(View.GONE,View.GONE);
isUserNameValid = false;
}
if (isUserNameValid) {
FirebaseDatabase.getInstance().getReference()
.child(KEY_COLLECTION_USER)
.child(finalQuery)
.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
User user = snapshot.getValue(User.class);
if (user.getUserName().equals(CURRENT_USER.getUserName())) continue;
if (user.getUserName().toLowerCase().startsWith(finalQuery.toLowerCase())) {
userMap.put(user.getId(),user);
}
checkList();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) { }
});
}
}
private void setViewsVisibility(int searchVis,int searchTipVis,int notFoundVis) {
searchUserRV.setVisibility(searchVis);
searchTipCV.setVisibility(searchTipVis);
notFoundTV.setVisibility(notFoundVis);
}
private void checkList() {
if (userMap.size() > 0) {
refreshRV(userMap);
setViewsVisibility(View.VISIBLE,View.GONE,View.GONE);
} else {
setViewsVisibility(View.GONE,View.VISIBLE);
}
}
private void refreshRV(@NotNull Map<String,User> userMap) {
SearchUserAdapter searchUserAdapter = new SearchUserAdapter(
getContext(),userMap
);
searchUserRV.setAdapter(searchUserAdapter);
}
public static void newInstance(String query) {
SearchUserFragment searchUserFragment = new SearchUserFragment();
searchUserFragment.searchUser(query);
}
}
SearchPagerAdapter.java
public class SearchPagerAdapter extends FragmentStateAdapter {
public SearchPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
@NonNull
@Override
public Fragment createFragment(int position) {
if (position == 0) {
return new SearchUserFragment();
} else {
return new SearchMessageFragment();
}
}
@Override
public int getItemCount() {
return 2;
}
}
我不明白为什么我在研究过程中发现的一些 newInstance() 方法会返回 Fragment 本身。我已经在 SearchUserFragment 中尝试了以下方法:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null && getArguments().containsKey(BUNDLE_SEARCH)) {
searchUser(savedInstanceState.getString(BUNDLE_SEARCH));
}
}
public static SearchUserFragment newInstance(String query) {
SearchUserFragment searchUserFragment = new SearchUserFragment();
Bundle args = new Bundle();
args.putString(BUNDLE_SEARCH,query);
searchUserFragment.setArguments(args);
return searchUserFragment;
}
但它没有成功,就像 newInstance() 没有实例化片段的另一个实例一样。应用不会崩溃,但当我在 SearchView 中输入内容时不会发生任何事情。
我也尝试过这样做: SearchActivity.java
@Override
public boolean onQueryTextChange(String query) {
if (!TextUtils.isEmpty(query)) {
if (currentFrag == FRAG_USERS) {
Bundle bundle = new Bundle();
bundle.putString(Constants.BUNDLE_SEARCH,query);
new SearchUserFragment().setArguments(bundle);
} else {
SearchMessageFragment.newInstance(query);
}
}
return true;
}
SearchUserFragment.java
@Override
public View onCreateView(@NonNull LayoutInflater inflater,false);
notFoundTV = view.findViewById(R.id.notFoundTV);
searchTipCV = view.findViewById(R.id.searchTipCV);
refreshRV(view);
Bundle bundle = this.getArguments();
if (bundle != null) {
searchUser(bundle.getString(BUNDLE_SEARCH));
}
return view;
}
也没有用。与上述相同的行为。
在代码的当前状态下,我得到 NullPointerException(理所当然)。当前代码使我所有的列表和视图都变为空,因为 onCreateView() 由于已经创建而没有被触发。
我只是希望能够从 SearchActivity 获取查询,以便完美地从片段中执行 searchUser()/searchMessage()。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)