滑动到新片段并滑动回 tabLayout 中的上一个片段时应用程序崩溃
app crashes when swipe to new fragment and swipe back to previous fragment in tabLayout
我有一个主片段,其中包含两个片段(片段 A 和 B),在工具栏上方有一个用于搜索的搜索图标。我的问题是,当我只在片段 A 和 B 之间滑动并使用搜索图标进行一些搜索过滤时,应用程序运行正常。但问题是,当我在主片段中添加另一个新片段 C 时,启动应用程序并滑动到片段 C,然后滑动回到片段 A 或 B,然后单击搜索图标,应用程序崩溃了。
这是崩溃日志
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.access0(MainActivity.java:50)
at com.example.welsenho.questfy_tw.MainUserActivity.MainActivity.onQueryTextChange(MainActivity.java:158)
at android.support.v7.widget.SearchView.onTextChanged(SearchView.java:1181)
at android.support.v7.widget.SearchView.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)
它说不能将片段 A 转换为片段 B,但我不明白的是,如果我没有滑动到片段 C(就在片段 A 和 B 之间),一切都会好起来的,但是滑动之后到 Fragment C 并滑回 Fragment A 或 B 并单击搜索图标然后应用程序将崩溃
主要代码 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);
}
}
}
}
}
}
主要片段代码
@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;
适配器代码
@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;
}
片段 A 和 B 中的代码仅用于从 firebase 检索数据并加载到 recyclerView。它说问题是由这条线 latestArticleFragment(Fragment A) = (MainActivityLatestArticleFragment) getSupportFragmentManager().getFragments().get(0).getChildFragmentManager().getFragments() 引起的。 get(0); 部分,但我不明白的是,当我不尝试滑动到 Fragment C 时,一切正常,但如果我确实滑动到 Fragment C 并滑动回 Fragment A & B 然后单击搜索图标应用程序将崩溃。我已经被这个问题困扰了大约 3 天,并尝试了一些解决方案,但它就是行不通。任何人都可以解释为什么我遇到这个问题以及如何解决它吗?
我的直觉是,如果将屏幕页面限制设置为大于 1,就不会遇到此问题。因此,在您的 MainFragment 的 onCreateView
中添加以下一行:
viewPager = view.findViewById(R.id.main_activity_viewpager);
// add below line
viewpager.setOffscreenPageLimit(2)
viewPager.setAdapter(new MainActivityTabAdapter(getChildFragmentManager(), Locale.getDefault().getDisplayLanguage()));
我有一个主片段,其中包含两个片段(片段 A 和 B),在工具栏上方有一个用于搜索的搜索图标。我的问题是,当我只在片段 A 和 B 之间滑动并使用搜索图标进行一些搜索过滤时,应用程序运行正常。但问题是,当我在主片段中添加另一个新片段 C 时,启动应用程序并滑动到片段 C,然后滑动回到片段 A 或 B,然后单击搜索图标,应用程序崩溃了。
这是崩溃日志
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.access0(MainActivity.java:50) at com.example.welsenho.questfy_tw.MainUserActivity.MainActivity.onQueryTextChange(MainActivity.java:158) at android.support.v7.widget.SearchView.onTextChanged(SearchView.java:1181) at android.support.v7.widget.SearchView.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)
它说不能将片段 A 转换为片段 B,但我不明白的是,如果我没有滑动到片段 C(就在片段 A 和 B 之间),一切都会好起来的,但是滑动之后到 Fragment C 并滑回 Fragment A 或 B 并单击搜索图标然后应用程序将崩溃
主要代码 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);
}
}
}
}
}
}
主要片段代码
@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;
适配器代码
@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;
}
片段 A 和 B 中的代码仅用于从 firebase 检索数据并加载到 recyclerView。它说问题是由这条线 latestArticleFragment(Fragment A) = (MainActivityLatestArticleFragment) getSupportFragmentManager().getFragments().get(0).getChildFragmentManager().getFragments() 引起的。 get(0); 部分,但我不明白的是,当我不尝试滑动到 Fragment C 时,一切正常,但如果我确实滑动到 Fragment C 并滑动回 Fragment A & B 然后单击搜索图标应用程序将崩溃。我已经被这个问题困扰了大约 3 天,并尝试了一些解决方案,但它就是行不通。任何人都可以解释为什么我遇到这个问题以及如何解决它吗?
我的直觉是,如果将屏幕页面限制设置为大于 1,就不会遇到此问题。因此,在您的 MainFragment 的 onCreateView
中添加以下一行:
viewPager = view.findViewById(R.id.main_activity_viewpager);
// add below line
viewpager.setOffscreenPageLimit(2)
viewPager.setAdapter(new MainActivityTabAdapter(getChildFragmentManager(), Locale.getDefault().getDisplayLanguage()));