【发布时间】:2021-08-16 22:10:46
【问题描述】:
我一直在研究这个问题,尽管我找到了信息,但似乎有些细节我没有掌握。我想将信息从 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.VISIBLE, 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.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, @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);
Bundle bundle = this.getArguments();
if (bundle != null) {
searchUser(bundle.getString(BUNDLE_SEARCH));
}
return view;
}
它也没有成功。与上述行为相同。
在代码的当前状态下,我得到了 NullPointerException(理所当然)。当前的代码使我所有的列表和视图都变为空,因为 onCreateView() 由于已经创建而没有被触发。
我只想能够从 SearchActivity 中获取查询,以便完美地从片段中执行 searchUser()/searchMessage()。
【问题讨论】:
-
这可能会有所帮助,您基本上需要对现有片段的引用,您可以直接调用该方法,无需捆绑:stackoverflow.com/questions/36503779/…
-
@DanielNugent 我需要为 ViewPager2 设置一个适配器吗?我已经更改了 SearchPagerAdapter 的代码,但我不确定如何处理 SearchActivity 上的 setupViewPager()。当我尝试设置它时,它给了我一个错误,因为 SearchPager 类是从 FragmentPagerAdapter 而不是从 FragmentStateAdapter 扩展的。
-
@DanielNugent 最后一个链接有我想要的。非常感谢:)
标签: android android-fragments android-activity android-bundle