嵌套片段 getchildfragmentmanager 导致崩溃
Nested fragments getchildfragmentmanager causing crash
我有包含片段的 viewPager 每个片段都有 viewpager 来显示图像和横幅
现在,我正在向每个片段图像适配器传递 getChildFragmentManager(),如下所示
CarouselAdapter carouselAdapter = new CarouselAdapter(getChildFragmentManager());
但是上面的代码在更改显示以下消息的 viewpager 选项卡时导致崩溃
java.lang.IllegalArgumentException: No view found for id 0x7f1000ef
但是,如果我传递 getFragmentManager() 它不会崩溃,但适配器会在一段时间内变为空白任何关于如何处理嵌套片段的想法。
我正在为两个 viewpager 使用 FragmentPagerAdapter,但仍然无法正常工作
以下是崩溃日志
java.lang.IllegalArgumentException: No view found for id 0x7f1000ef (com.packagename:id/viewPagerBanners) for fragment MainBannerFragmentNew{308cb84 #0 id=0x7f1000ef android:switcher:2131755247:0}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1292)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1523)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1585)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2832)
at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:2199)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1323)
at android.support.v4.app.FragmentManagerImpl.moveFragmentsToInvisible(FragmentManager.java:2323)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2136)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2092)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1969)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:620)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:143)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1268)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
at android.support.v4.view.ViewPager.run(ViewPager.java:273)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:603)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
以下为轮播适配器代码
public class CarouselAdapter extends FragmentPagerAdapter {
private List<CarouselItem> carouselItemsList;
public CarouselAdapter(FragmentManager fm, List<CarouselItem> carouselItemsList) {
super(fm);
this.carouselItemsList = carouselItemsList;
}
@Override
public Fragment getItem(int position) {
return MainBannerFragmentNew.newInstance(R.drawable.gray_logo, carouselItemsList.get(position));
}
@Override
public int getCount() {
return carouselItemsList.size();
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
}
以下是滑动标签适配代码
public class HomeTabsPagerAdapter extends FragmentPagerAdapter {
ArrayList<HomeTabItem> homeTabItems;
public HomeTabsPagerAdapter(FragmentManager manager, ArrayList<HomeTabItem> homeTabItems) {
super(manager);
this.homeTabItems = homeTabItems;
}
@Override
public Fragment getItem(int position) {
HomeTabItem homeTabItem = homeTabItems.get(position);
return OfferZoneFragment.newInstance(homeTabItem.getId());
}
@Override
public int getCount() {
return homeTabItems.size();
}
@Override
public CharSequence getPageTitle(int position) {
return homeTabItems.get(position).getTitle();
}
}
每个sliding tab fragment都有recyclerview这个recylerview包含carousel viewpager下面是bindview中的代码
((BannerHolder) holder).viewPager.setAdapter(new CarouselAdapter(fragmentManager, homePageItems.get(position).carouselItems));
((BannerHolder) holder).circlePageIndicator.setViewPager(((BannerHolder) holder).viewPager);
final float density = context.getResources().getDisplayMetrics().density;
((BannerHolder) holder).circlePageIndicator.setBackgroundColor(0x00000000);
((BannerHolder) holder).circlePageIndicator.setRadius(5 * density);
((BannerHolder) holder).circlePageIndicator.setFillColor(ContextCompat.getColor(context, R.color.appthemecolor));
((BannerHolder) holder).circlePageIndicator.setPageColor(0xFFFFFFFF);
((BannerHolder) holder).circlePageIndicator.setStrokeColor(0x00000000);
((BannerHolder) holder).circlePageIndicator.setStrokeWidth(2 * density);
if (((BannerHolder) holder).viewPager.getAdapter().getCount() <= 1) {
((BannerHolder) holder).circlePageIndicator.setVisibility(View.GONE);
} else {
((BannerHolder) holder).circlePageIndicator.setVisibility(View.VISIBLE);
}
您正在使用 getChildFragmentManager
作为嵌套片段,这是正确的。
你在做什么:
在您的情况下,当片段想要附加到(child 的)viewpager 但这里的 viewpager 没有附加到它的 parent(仍然分离)。
你应该做什么:
创建自定义 ViewPager
覆盖其 onAttachedToWindow
并执行延迟设置适配器。
有关详细信息,请查看 IllegalArgumentException: No view found for id for fragment — ViewPager in ViewPager。
更新:
如果您想使用 getFragmentManager
或 getSupportFragmentManager
而不是将 PagerAdapter
的 parent class 从 android.support.v4.app.FragmentPagerAdapter
更改为 android.support.v4.app.FragmentStatePagerAdapter
.
用 FragmentStatePagerAdapter 替换 FragmentPagerAdapter 为子片段和父片段解决了我的问题。
我有包含片段的 viewPager 每个片段都有 viewpager 来显示图像和横幅
现在,我正在向每个片段图像适配器传递 getChildFragmentManager(),如下所示
CarouselAdapter carouselAdapter = new CarouselAdapter(getChildFragmentManager());
但是上面的代码在更改显示以下消息的 viewpager 选项卡时导致崩溃
java.lang.IllegalArgumentException: No view found for id 0x7f1000ef
但是,如果我传递 getFragmentManager() 它不会崩溃,但适配器会在一段时间内变为空白任何关于如何处理嵌套片段的想法。
我正在为两个 viewpager 使用 FragmentPagerAdapter,但仍然无法正常工作
以下是崩溃日志
java.lang.IllegalArgumentException: No view found for id 0x7f1000ef (com.packagename:id/viewPagerBanners) for fragment MainBannerFragmentNew{308cb84 #0 id=0x7f1000ef android:switcher:2131755247:0}
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1292)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1523)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1585)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2832)
at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:2199)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1323)
at android.support.v4.app.FragmentManagerImpl.moveFragmentsToInvisible(FragmentManager.java:2323)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2136)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2092)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1969)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:620)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:143)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1268)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
at android.support.v4.view.ViewPager.run(ViewPager.java:273)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
at android.view.Choreographer.doCallbacks(Choreographer.java:670)
at android.view.Choreographer.doFrame(Choreographer.java:603)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
以下为轮播适配器代码
public class CarouselAdapter extends FragmentPagerAdapter {
private List<CarouselItem> carouselItemsList;
public CarouselAdapter(FragmentManager fm, List<CarouselItem> carouselItemsList) {
super(fm);
this.carouselItemsList = carouselItemsList;
}
@Override
public Fragment getItem(int position) {
return MainBannerFragmentNew.newInstance(R.drawable.gray_logo, carouselItemsList.get(position));
}
@Override
public int getCount() {
return carouselItemsList.size();
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
}
以下是滑动标签适配代码
public class HomeTabsPagerAdapter extends FragmentPagerAdapter {
ArrayList<HomeTabItem> homeTabItems;
public HomeTabsPagerAdapter(FragmentManager manager, ArrayList<HomeTabItem> homeTabItems) {
super(manager);
this.homeTabItems = homeTabItems;
}
@Override
public Fragment getItem(int position) {
HomeTabItem homeTabItem = homeTabItems.get(position);
return OfferZoneFragment.newInstance(homeTabItem.getId());
}
@Override
public int getCount() {
return homeTabItems.size();
}
@Override
public CharSequence getPageTitle(int position) {
return homeTabItems.get(position).getTitle();
}
}
每个sliding tab fragment都有recyclerview这个recylerview包含carousel viewpager下面是bindview中的代码
((BannerHolder) holder).viewPager.setAdapter(new CarouselAdapter(fragmentManager, homePageItems.get(position).carouselItems));
((BannerHolder) holder).circlePageIndicator.setViewPager(((BannerHolder) holder).viewPager);
final float density = context.getResources().getDisplayMetrics().density;
((BannerHolder) holder).circlePageIndicator.setBackgroundColor(0x00000000);
((BannerHolder) holder).circlePageIndicator.setRadius(5 * density);
((BannerHolder) holder).circlePageIndicator.setFillColor(ContextCompat.getColor(context, R.color.appthemecolor));
((BannerHolder) holder).circlePageIndicator.setPageColor(0xFFFFFFFF);
((BannerHolder) holder).circlePageIndicator.setStrokeColor(0x00000000);
((BannerHolder) holder).circlePageIndicator.setStrokeWidth(2 * density);
if (((BannerHolder) holder).viewPager.getAdapter().getCount() <= 1) {
((BannerHolder) holder).circlePageIndicator.setVisibility(View.GONE);
} else {
((BannerHolder) holder).circlePageIndicator.setVisibility(View.VISIBLE);
}
您正在使用 getChildFragmentManager
作为嵌套片段,这是正确的。
你在做什么:
在您的情况下,当片段想要附加到(child 的)viewpager 但这里的 viewpager 没有附加到它的 parent(仍然分离)。
你应该做什么:
创建自定义 ViewPager
覆盖其 onAttachedToWindow
并执行延迟设置适配器。
有关详细信息,请查看 IllegalArgumentException: No view found for id for fragment — ViewPager in ViewPager。
更新:
如果您想使用 getFragmentManager
或 getSupportFragmentManager
而不是将 PagerAdapter
的 parent class 从 android.support.v4.app.FragmentPagerAdapter
更改为 android.support.v4.app.FragmentStatePagerAdapter
.
用 FragmentStatePagerAdapter 替换 FragmentPagerAdapter 为子片段和父片段解决了我的问题。