Tablayout / Viewpager 内的空白片段
Blank Fragment inside Tablayout / Viewpager
所以我正在拼命寻找我的问题的答案。我花了几个小时尝试并重试一些事情,但那没有用。
所以这是我的问题:
我的应用程序只有一个 activity,这是主要的 activity。
此 activity 包含一个底部导航栏和一个框架布局,用于根据底部导航栏上项目的选择加载片段。
我的 PredictionsFragment(由底部导航栏加载)包含一个 TabLayout(使用 SmartTabLayout 库)。在此片段中,数据列表在线程中加载,因为它使用互联网连接。 TabLayout 包含显示 RecyclerView 的 PredictionsViewFragment。
当我 select 底部导航栏上的 PredictionsFragment 时,tablayout 和所有 recyclerview 都完美显示。
但是当我转到另一个项目并返回到 PredictionsFragment 时,它显示一个空白视图...
PredictionsFragment 代码:
public class PredictionsFragment extends Fragment {
private static List<Country> countryList = new ArrayList<>();
private ViewPager viewPager;
private SmartTabLayout viewPagerTab;
private FragmentStatePagerItemAdapter adapter;
private FragmentPagerItems pages;
private ProgressBar progressBar;
private ViewGroup tab;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_predictions_tab, container, false);
initView(view);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (countryList.size() == 0) {
refresh();
} else {
refreshViewPager();
}
}
private void initView(View view) {
tab = (ViewGroup) view.findViewById(R.id.tab);
tab.addView(LayoutInflater.from(getContext()).inflate(R.layout.fragment_view_predictions, tab, false));
progressBar = (ProgressBar) view.findViewById(R.id.progressbar);
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPagerTab = (SmartTabLayout) view.findViewById(R.id.viewpagertab);
viewPager.setOffscreenPageLimit(countryList.size());
pages = new FragmentPagerItems(getContext());
adapter = new FragmentStatePagerItemAdapter(getFragmentManager(), pages){
public int getItemPosition(Object object) {
return POSITION_NONE;
}
};
viewPager.setAdapter(adapter);
viewPagerTab.setViewPager(viewPager);
}
private void refresh() {
// Thread car connexion internet
new Thread(new Runnable() {
@Override
public void run() {
countryList = InternetData.getCountryList();
refreshViewPager();
}
}).start();
}
private void refreshViewPager() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
for (Country country : countryList) {
pages.add(FragmentPagerItem.of(country.getCode(), PredictionsViewFragment.class));
}
adapter.notifyDataSetChanged();
viewPagerTab.setViewPager(viewPager);
progressBar.setVisibility(View.GONE);
}
});
}
public static List<Prediction> getPredictionList(int index) {
return countryList.get(index).getPredictionList();
}
}
PredictionsViewFragment 代码:
public class PredictionsViewFragment extends Fragment {
private RecyclerView recyclerView;
private PredictionAdapter adapter;
private int position;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.recycler_view_pronos, container, false);
position = FragmentPagerItem.getPosition(getArguments());
initRecyclerView(view);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
private void initRecyclerView(View view) {
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
adapter = new PredictionAdapter(PredictionsFragment.getPredictionList(position));
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(adapter);
}
}
Screenshot of the blank fragment and the app
编辑:
当我使用 getChildFragmentManager() 方法时:
adapter = new FragmentStatePagerItemAdapter(getChildFragmentManager(), pages){
public int getItemPosition(Object object) {
return POSITION_NONE;
}
};
当我第二次使用 Fragment 时出现此错误(我第一次使用它时,它运行良好):
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.util.SparseArray.get(int)' on a null object reference
at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:936)
at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:217)
at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1461)
at android.view.View.dispatchRestoreInstanceState(View.java:18608)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3821)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3827)
at android.view.View.restoreHierarchyState(View.java:18586)
at android.support.v4.app.Fragment.restoreViewState(Fragment.java:494)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1486)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at android.support.v4.app.FragmentManagerImpl.run(FragmentManager.java:733)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
编辑 2:
我将这些行添加到 PredictionsFragment 的 onViewCreated 方法中:
else {
refreshViewPager();
}
但它什么也没做...选项卡的名称正确显示但不是 recyclerview...
好像tablayout里面的Fragment没有加载
编辑 3:
我在我的 recyclerview 中添加了一个 SwipeRefreshLayout,对于前 2 个选项卡,我无法进行拉动刷新,而在第 3 个选项卡中,只有一个 recyclerview 项目出现并拉动刷新 "works" 但它只显示一个项目在回收站视图中
如果您有任何问题,请告诉我,我会尽力解答!
在此先感谢您的帮助,我很感激
在 viewPager 中使用 setOffsetScreenPageLimit
:这将帮助您在浏览底部选项卡时将数据存储在寻呼机片段中。
viewPager.setOffscreenPageLimit(the number of tab you are setting);
- 要在回收站视图中刷新数据,您可以使用"Swipe refresh"
所以我解决了我的问题...
你必须使用这个:
adapter = new FragmentPagerItemAdapter(getChildFragmentManager(), pages);
使用 FragmentPagerItemAdapter 而不 FragmentStatePagerItemAdapter
对于 sur 你必须使用 getChildFragmentManager()
我也使用 BottomNavigationView 打开带有 viewPager 的 tabLayout & 遇到了同样的问题。 FragmentStatePagerAdapter 可用于此。
这个 class 处理片段状态的保存和恢复 -> It's in the documentation
所以我正在拼命寻找我的问题的答案。我花了几个小时尝试并重试一些事情,但那没有用。 所以这是我的问题:
我的应用程序只有一个 activity,这是主要的 activity。 此 activity 包含一个底部导航栏和一个框架布局,用于根据底部导航栏上项目的选择加载片段。
我的 PredictionsFragment(由底部导航栏加载)包含一个 TabLayout(使用 SmartTabLayout 库)。在此片段中,数据列表在线程中加载,因为它使用互联网连接。 TabLayout 包含显示 RecyclerView 的 PredictionsViewFragment。 当我 select 底部导航栏上的 PredictionsFragment 时,tablayout 和所有 recyclerview 都完美显示。 但是当我转到另一个项目并返回到 PredictionsFragment 时,它显示一个空白视图...
PredictionsFragment 代码:
public class PredictionsFragment extends Fragment {
private static List<Country> countryList = new ArrayList<>();
private ViewPager viewPager;
private SmartTabLayout viewPagerTab;
private FragmentStatePagerItemAdapter adapter;
private FragmentPagerItems pages;
private ProgressBar progressBar;
private ViewGroup tab;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_predictions_tab, container, false);
initView(view);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (countryList.size() == 0) {
refresh();
} else {
refreshViewPager();
}
}
private void initView(View view) {
tab = (ViewGroup) view.findViewById(R.id.tab);
tab.addView(LayoutInflater.from(getContext()).inflate(R.layout.fragment_view_predictions, tab, false));
progressBar = (ProgressBar) view.findViewById(R.id.progressbar);
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPagerTab = (SmartTabLayout) view.findViewById(R.id.viewpagertab);
viewPager.setOffscreenPageLimit(countryList.size());
pages = new FragmentPagerItems(getContext());
adapter = new FragmentStatePagerItemAdapter(getFragmentManager(), pages){
public int getItemPosition(Object object) {
return POSITION_NONE;
}
};
viewPager.setAdapter(adapter);
viewPagerTab.setViewPager(viewPager);
}
private void refresh() {
// Thread car connexion internet
new Thread(new Runnable() {
@Override
public void run() {
countryList = InternetData.getCountryList();
refreshViewPager();
}
}).start();
}
private void refreshViewPager() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
for (Country country : countryList) {
pages.add(FragmentPagerItem.of(country.getCode(), PredictionsViewFragment.class));
}
adapter.notifyDataSetChanged();
viewPagerTab.setViewPager(viewPager);
progressBar.setVisibility(View.GONE);
}
});
}
public static List<Prediction> getPredictionList(int index) {
return countryList.get(index).getPredictionList();
}
}
PredictionsViewFragment 代码:
public class PredictionsViewFragment extends Fragment {
private RecyclerView recyclerView;
private PredictionAdapter adapter;
private int position;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.recycler_view_pronos, container, false);
position = FragmentPagerItem.getPosition(getArguments());
initRecyclerView(view);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
private void initRecyclerView(View view) {
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
adapter = new PredictionAdapter(PredictionsFragment.getPredictionList(position));
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(adapter);
}
}
Screenshot of the blank fragment and the app
编辑:
当我使用 getChildFragmentManager() 方法时:
adapter = new FragmentStatePagerItemAdapter(getChildFragmentManager(), pages){
public int getItemPosition(Object object) {
return POSITION_NONE;
}
};
当我第二次使用 Fragment 时出现此错误(我第一次使用它时,它运行良好):
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.util.SparseArray.get(int)' on a null object reference
at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:936)
at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:217)
at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1461)
at android.view.View.dispatchRestoreInstanceState(View.java:18608)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3821)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3827)
at android.view.View.restoreHierarchyState(View.java:18586)
at android.support.v4.app.Fragment.restoreViewState(Fragment.java:494)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1486)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at android.support.v4.app.FragmentManagerImpl.run(FragmentManager.java:733)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
编辑 2:
我将这些行添加到 PredictionsFragment 的 onViewCreated 方法中:
else {
refreshViewPager();
}
但它什么也没做...选项卡的名称正确显示但不是 recyclerview... 好像tablayout里面的Fragment没有加载
编辑 3: 我在我的 recyclerview 中添加了一个 SwipeRefreshLayout,对于前 2 个选项卡,我无法进行拉动刷新,而在第 3 个选项卡中,只有一个 recyclerview 项目出现并拉动刷新 "works" 但它只显示一个项目在回收站视图中
如果您有任何问题,请告诉我,我会尽力解答! 在此先感谢您的帮助,我很感激
在 viewPager 中使用 setOffsetScreenPageLimit
:这将帮助您在浏览底部选项卡时将数据存储在寻呼机片段中。
viewPager.setOffscreenPageLimit(the number of tab you are setting);
- 要在回收站视图中刷新数据,您可以使用"Swipe refresh"
所以我解决了我的问题...
你必须使用这个:
adapter = new FragmentPagerItemAdapter(getChildFragmentManager(), pages);
使用 FragmentPagerItemAdapter 而不 FragmentStatePagerItemAdapter 对于 sur 你必须使用 getChildFragmentManager()
我也使用 BottomNavigationView 打开带有 viewPager 的 tabLayout & 遇到了同样的问题。 FragmentStatePagerAdapter 可用于此。
这个 class 处理片段状态的保存和恢复 -> It's in the documentation