I have a Main fragment that contains two fragments (fragment A & B), and above in the toolBar there is a search icon for search purpose. My problem is when I just only swipe between fragment A & B and use the search icon to do some search filter, the app works OK. But the problem is when I add another new fragment C in the Main fragment, after starting the app and swipe to fragment C then swipe back to fragment A or B, then click the search icon, the app crashed.
Here is the crash log
2019-03-07 22:52:10.616 28866-28866/com.example.welsenho.questfy_tw E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.welsenho.questfy_tw, PID: 28866 java.lang.ClassCastException: com.example.welsenho.questfy_tw.MainActivityFragment.MostPopularFragment cannot be cast to com.example.welsenho.questfy_tw.MainActivityFragment.MainActivityLatestArticleFragment at com.example.welsenho.questfy_tw.MainUserActivity.MainActivity.searchFilter(MainActivity.java:303) at com.example.welsenho.questfy_tw.MainUserActivity.MainActivity.access$200(MainActivity.java:50) at com.example.welsenho.questfy_tw.MainUserActivity.MainActivity$1.onQueryTextChange(MainActivity.java:158) at android.support.v7.widget.SearchView.onTextChanged(SearchView.java:1181) at android.support.v7.widget.SearchView$10.onTextChanged(SearchView.java:1715) at android.widget.TextView.sendOnTextChanged(TextView.java:9364) at android.widget.TextView.setText(TextView.java:5397) at android.widget.TextView.setText(TextView.java:5250) at android.widget.EditText.setText(EditText.java:113) at android.widget.TextView.setText(TextView.java:5207) at android.support.v7.widget.SearchView.onActionViewExpanded(SearchView.java:1295) at android.support.v7.widget.Toolbar$ExpandedActionViewMenuPresenter.expandItemActionView(Toolbar.java:2397)
It says that Fragment A cannot be cast to Fragment B, but what I don't understand is that if I did not swipe to Fragment C (Just between Fragment A & B) everything will be just fine but after swiping to Fragment C and swipe back to Fragment A or B and click the search icon then the app will crash
code for the Main Activity
private void searchFilter(String inputText, ArrayList<FirebaseDatabaseGetSet> decidedFilterList) {
Log.d("TAG", "searchFilter");
ArrayList<FirebaseDatabaseGetSet> filterList = new ArrayList<>();
if (!filterList.isEmpty()) {
filterList.clear();
}
MainActivityLatestArticleFragment latestArticleFragment;
MostPopularFragment mostPopularFragment;
MainSubjectChooseFragment mainSubjectChooseFragment;
//MainSubjectChooseFragment mainSubjectChooseFragment(Fragment C) = (MainSubjectChooseFragment) getSupportFragmentManager().getFragments().get(0).getChildFragmentManager() .getFragments().get(2);
latestArticleFragment(Fragment A) = (MainActivityLatestArticleFragment) getSupportFragmentManager().getFragments().get(0).getChildFragmentManager().getFragments().get(0);
mostPopularFragment(Fragment B) = (MostPopularFragment) getSupportFragmentManager().getFragments().get(0).getChildFragmentManager().getFragments().get(1);
Log.d("TAG", "Fragment");
for (FirebaseDatabaseGetSet firebaseDatabaseGetSet : decidedFilterList) {
if (firebaseDatabaseGetSet.getTitle().toLowerCase().contains(inputText.toLowerCase())) {
filterList.add(firebaseDatabaseGetSet);
if (currentFilterPage == 0) {
Log.d("TAG", "Fragment0");
if (latestArticleFragment != null) {
Log.d("TAG", "notNull");
if (!filterList.isEmpty()) {
Log.d("TAG", "filter");
latestArticleFragment.returnFilterList(filterList);
}
}
} else if (currentFilterPage == 1) {
Log.d("TAG", "Fragment1");
if (mostPopularFragment != null) {
if (!filterList.isEmpty()) {
mostPopularFragment.returnFilterList(filterList);
}
}
}
}
}
}
code for Main Fragment
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_main_activity_tab, container, false);
tabLayout = view.findViewById(R.id.main_activity_tabLayout);
viewPager = view.findViewById(R.id.main_activity_viewpager);
viewPager.setAdapter(new MainActivityTabAdapter(getChildFragmentManager(), Locale.getDefault().getDisplayLanguage()));
tabLayout.post(new Runnable() {
@Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
mListener.getTabCurrentPage(i);
}
@Override
public void onPageSelected(int i) {
mListener.getTabCurrentPage(i);
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
return view;
code for the adapter
@Override
public Fragment getItem(int i) {
switch (i){
case 0: return new MainActivityLatestArticleFragment();
case 1: return new MostPopularFragment();
case 2: return new MainSubjectChooseFragment();
}
return null;
}
@Override
public int getCount() {
return 3;
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
if (language.equals("中文")) {
switch (position) {
case 0:
return "最新文章";
case 1:
return "熱門文章";
case 2:
return "相關科系";
}
}else {
switch (position) {
case 0:
return "Latest Article";
case 1:
return "Most Popular";
case 2:
return "Program Select";
}
}
return null;
}
code in Fragment A & B are just for only retrieving data from firebase and load into recyclerView. It says the problem was cause by this line latestArticleFragment(Fragment A) = (MainActivityLatestArticleFragment) getSupportFragmentManager().getFragments().get(0).getChildFragmentManager().getFragments().get(0); part, but I don't get it is that when I'm not trying to swipe to Fragment C everything works smoothly, but if I did swipe to Fragment C and swipe back to Fragment A & B then click the search icon the app will crashed. I have beed bothered by this problem for like 3 days already and tried some solution but it just can not work. Can anyone explain why I am having this problem and how I can fix it?
My hunch is if you set off screen page limit to more than 1, you will not face the issue. So in your MainFragment's onCreateView
add the following one line:
viewPager = view.findViewById(R.id.main_activity_viewpager);
// add below line
viewpager.setOffscreenPageLimit(2)
viewPager.setAdapter(new MainActivityTabAdapter(getChildFragmentManager(), Locale.getDefault().getDisplayLanguage()));