android–IllegalArgumentException:找不到用于片段的id的视图 –ViewPager中的ViewPager

android–IllegalArgumentException:找不到用于片段的id的视图 –ViewPager中的ViewPager,第1张

概述我遇到了困扰我好几天的问题.主活动中有一个ViewPager,它将3个片段作为制表符片段保存.在第一个片段中有一个ListView,它包含一些视图,其中最重要的是另一个ViewPager.我想在子ViewPager中保存一些照片,并在这里使用更多片段.现在有麻烦:当第一个Fragment停止时(在屏幕上看到父Vi

我遇到了困扰我好几天的问题.

主活动中有一个VIEwPager,它将3个片段作为制表符片段保存.在第一个片段中有一个ListVIEw,它包含一些视图,其中最重要的是另一个VIEwPager.我想在子VIEwPager中保存一些照片,并在这里使用更多片段.

现在有麻烦:
当第一个Fragment停止时(在屏幕上看到父VIEwPager中的第三个片段)并恢复(用户切换到第二个片段),应用程序崩溃,调试器说:

@H_301_11@java.lang.IllegalArgumentException: No vIEw found for ID 0x7f05008b (com.example.vIEwpager:ID/sub_vIEwpager) for fragment ScreenSlIDePageFragment

我已经使用了getChildFragmentManager(),因为这是nested fragments的情况.

以下是与父VIEwPager中第一个片段对应的列表适配器的关键代码:

@H_301_11@@OverrIDepublic VIEw getVIEw(int position, VIEw convertVIEw, VIEwGroup parent) {    int type = getItemVIEwType(position);    switch (type) {        case TYPE_BANNER:            if (convertVIEw == null) {                convertVIEw = mBannerVIEw.getBannerVIEw(parent);            }            mBannerVIEw.update(convertVIEw);            break;        case TYPE_ITEM:            break;    }    return convertVIEw;}

这是mBannerVIEw的代码:

@H_301_11@public class BannerVIEw {    private static final displayImageOptions IMAGE_OPTIONS_SCALE_@R_609_4041@ =            new displayImageOptions.Builder()                    .cacheInMemory()                    .cacheOndisc()                    .imageScaleType(ImageScaleType.EXACTLY_@R_609_4041@)                    .build();    private FragmentActivity mActivity;    private Fragment mFragment;    private List<Banner> mBanners;    private ScreenSlIDePagerAdapter mPagerAdapter;    private VIEwPager mVIEwPager;    public BannerVIEw(FragmentActivity activity, Fragment fragment) {        mActivity = activity;        mFragment = fragment;    }    public voID update(VIEw convertVIEw) {        mVIEwPager = (VIEwPager) convertVIEw;        if (mBanners != null && !mBanners.isEmpty()) {            if (mPagerAdapter == null) {                mPagerAdapter = new ScreenSlIDePagerAdapter(mFragment.getChildFragmentManager());                mVIEwPager.setAdapter(mPagerAdapter);            }        }        mVIEwPager.setonClickListener(new VIEw.OnClickListener() {            @OverrIDe            public voID onClick(VIEw v) {                if (mOnBannerClickListener != null) {                    mOnBannerClickListener.onBannerClick();                }            }        });    }    class ScreenSlIDePagerAdapter extends FragmentStatePagerAdapter {        public ScreenSlIDePagerAdapter(FragmentManager fm) {            super(fm);        }        @OverrIDe        public Fragment getItem(int position) {            return new ScreenSlIDePageFragment(mBanners.get(position).getimageUrl());        }        @OverrIDe        public int getCount() {            return mBanners == null ? 0 : mBanners.size();        }    }    class ScreenSlIDePageFragment extends Fragment {        private String mUrl;        ScreenSlIDePageFragment(String url) {            super();            mUrl = url;        }        @OverrIDe        public VIEw onCreateVIEw(LayoutInflater inflater, VIEwGroup container,                                 Bundle savedInstanceState) {            VIEw vIEw = inflater.inflate(R.layout.item_banner, container, false);            if (vIEw != null) {                ImageVIEw imageVIEw = (ImageVIEw) vIEw.findVIEwByID(R.ID.item_banner_image);                imageVIEw.setLayoutParams(new linearLayout.LayoutParams(                        linearLayout.LayoutParams.MATCH_PARENT, linearLayout.LayoutParams.MATCH_PARENT));                ImageLoader.getInstance().displayImage(mUrl, imageVIEw, IMAGE_OPTIONS_SCALE_@R_609_4041@);            }            return vIEw;        }    }}

这是详细的错误列表:

@H_301_11@11-10 18:12:19.217    1444-1444/? E/MessageQueue-JNI﹕ java.lang.IllegalArgumentException: No vIEw found for ID 0x7f05008b (com.example.vIEwpager:ID/sub_vIEwpager) for fragment ScreenSlIDePageFragment{428d8ea0 #0 ID=0x7f05008b}        at androID.support.v4.app.FragmentManagerImpl.movetoState(FragmentManager.java:919)        at androID.support.v4.app.FragmentManagerImpl.movetoState(FragmentManager.java:1104)        at androID.support.v4.app.FragmentManagerImpl.movetoState(FragmentManager.java:1086)        at androID.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1884)        at androID.support.v4.app.Fragment.performActivityCreated(Fragment.java:1514)        at androID.support.v4.app.FragmentManagerImpl.movetoState(FragmentManager.java:947)        at androID.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1280)        at androID.support.v4.app.BackStackRecord.run(BackStackRecord.java:672)        at androID.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)        at androID.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472)        at androID.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)        at androID.support.v4.vIEw.VIEwPager.populate(VIEwPager.java:1068)        at androID.support.v4.vIEw.VIEwPager.populate(VIEwPager.java:914)        at androID.support.v4.vIEw.VIEwPager$3.run(VIEwPager.java:244)        at androID.support.v4.vIEw.VIEwPager.completeScroll(VIEwPager.java:1761)        at androID.support.v4.vIEw.VIEwPager.onIntercepttouchEvent(VIEwPager.java:1896)        at androID.vIEw.VIEwGroup.dispatchtouchEvent(VIEwGroup.java:1854)        at androID.vIEw.VIEwGroup.dispatchtransformedtouchEvent(VIEwGroup.java:2211)        at androID.vIEw.VIEwGroup.dispatchtouchEvent(VIEwGroup.java:1912)        at androID.vIEw.VIEwGroup.dispatchtransformedtouchEvent(VIEwGroup.java:2211)        at androID.vIEw.VIEwGroup.dispatchtouchEvent(VIEwGroup.java:1912)        at androID.vIEw.VIEwGroup.dispatchtransformedtouchEvent(VIEwGroup.java:2211)        at androID.vIEw.VIEwGroup.dispatchtouchEvent(VIEwGroup.java:1912)        at com.androID.internal.policy.impl.PhoneWindow$DecorVIEw.superdispatchtouchEvent(PhoneWindow.java:2228)        at com.androID.internal.policy.impl.PhoneWindow.superdispatchtouchEvent(PhoneWindow.java:1471)        at androID.app.Activity.dispatchtouchEvent(Activity.java:2424)        at com.androID.internal.policy.impl.PhoneWindow$DecorVIEw.dispatchtouchEvent(PhoneWindow.java:2176)        at androID.vIEw.VIEw.dispatchPointerEvent(VIEw.java:7571)        at androID.vIEw.VIEwRootImpl$VIEwPostImeinputStage.processpointerEvent(VIEwRootImpl.java:3883)        at androID.vIEw.VIEwRootImpl$VIEwPostImeinputStage.onProcess(VIEwRootImpl.java:3778)        at androID.vIEw.VIEwRootImpl$inputStage.deliver(VIEwRootImpl.java:3379)        at androID.vIEw.VIEwRootImpl$inputStage.onDeliverToNext(VIEwRootImpl.java:3429)        at androID.vIEw.VIEwRootImpl$inputStage.forward(VIEwRootImpl.java:3398)        at androID.vIEw.VIEwRootImpl$AsyncinputStage.forward(VIEwRootImpl.java:3483)        at androID.vIEw.VIEwRootImpl$inputStage.apply(VIEwRootImpl.java:3406)        at androID.vIEw.VIEwRootImpl$AsyncinputStage.apply(VIEwRootImpl.java:3540)        at androID.vIEw.VIEwRootImpl$inputStage.deliver(VIEwRootImpl.java:3379)        at androID.vIEw.VIEwRootImpl$inputStage.onDeliverToNext(VIEwRootImpl.java:3429)        at androID.vIEw.VIEwRootImpl$inputStage.forward(VIEwRootImpl.java:3398)        at androID.vIEw.VIEwRootImpl$inputStage.apply(VIEwRootImpl.java:3406)        at androID.vIEw.VIEwRootImpl$inputStage.deliver(VIEwRootImpl.java:3379)        at androID.vIEw.VIEwRootImpl.deliverinputEvent(VIEwRootImpl.java:5419)        at androID.vIEw.VIEwRootImpl.doProcessinputEvents(VIEwRootImpl.java:5399)        at androID.vIEw.VIEwRootImpl.enqueueinputEvent(VIEwRootImpl.java:5370)        at androID.vIEw.VIEwRootImpl$WindowinputEventReceiver.oninputEvent(VIEwRootImpl.java:5493)        at androID.vIEw.inputEventReceiver.dispatchinputEvent(inputEventReceiver.java:182)        at androID.os.MessageQueue.nativePollOnce(Native Method)        at androID.os.MessageQueue.next(MessageQueue.java:132)        at androID.os.Looper.loop(Looper.java:124)        at androID.app.ActivityThread.main(ActivityThread.java:5289)        at java.lang

解决方法:

更新:

我已经阅读了FragmentManager的源代码,最后得到了真正的原因:当vIEwpager附加到其父级之前,片段想要附加到vIEwpager时会发生此异常.换句话说,在getVIEw()方法返回之前,片段会膨胀.然后调用VIEwPager容器的findVIEwByID()方法,但VIEwPager仍处于分离状态,因此找到null并抛出IllegalArgumentException.

解决方案是创建自定义viewPager并延迟设置适配器:

@H_301_11@public class BannerVIEwPager extends VIEwPager {    PagerAdapter mPagerAdapter;    @OverrIDe    protected voID onAttachedToWindow() {        super.onAttachedToWindow();        if (mPagerAdapter != null) {            super.setAdapter(mPagerAdapter);            mPageIndicator.setVIEwPager(this);        }    }    @OverrIDe    public voID setAdapter(PagerAdapter adapter) {    }    public voID storeAdapter(PagerAdapter pagerAdapter) {        mPagerAdapter = pagerAdapter;    }    public BannerVIEwPager(Context context) {        super(context);    }    public BannerVIEwPager(Context context, AttributeSet attrs) {        super(context, attrs);    }}

在getVIEw()方法中,使用storeAdapter()而不是setAdapter.

以下陈述不正确.上面的话就是实际的原因.

最后我得到了答案.它由两部分组成.

>在父VIEwPager中,我使用FragmentPagerAdapter来保存片段,但现在我使用FragmentStatePagerAdapter.这两者之间的区别可以在这里找到:Difference between FragmentPagerAdapter and FragmentStatePagerAdapter.
简单来说,FragmentPagerAdapter将在片段停止时存储更多信息.在这种情况下,父VIEwPager中的第一个片段会被停止但不会被销毁,而此片段中的视图将被销毁.恢复后,片段尝试重新膨胀所有视图.但是在调用getVIEw()方法并重新创建子VIEwPager之前,子FragmentManager尝试查找子VIEwPager以保存先前存储的片段.因此,出现“java.lang.IllegalArgumentException:找不到ID的视图”.
>用FragmentStatePagerAdapter替换FragmentPagerAdapter后,出现另一个问题.当父片段(父视图中的第一个片段)被停止,销毁和恢复时,子视图抓取器丢失.当选择第一个片段时很快就会发生这种情况,之后很快就会选择第三个片段,最后重新选择第一个片段.
我认为这是androID sdk的一个BUG.灵感来自here和here,我使用一些棘手的方法来解决问题.关键是,当一个父片段被销毁时,字段成员— mChildFragmentManager“最终会破坏内部状态”并且不会被彻底清除.重新创建父片段时,mChildFragmentManager不为null,但子片段在被销毁之后已被销毁,该片段由mChildFragmentManager管理.因此,子VIEwPager在屏幕上显示一个空视图,该视图响应实际上不存在的假片段.有趣的是,在子VIEwPager上直接滑动几次后,子片段和视图再次出现.

这是代码:

父适配器:

@H_301_11@@OverrIDepublic VIEw getVIEw(int position, VIEw convertVIEw, VIEwGroup parent) {    if (convertVIEw == null) {        convertVIEw = getBannerVIEw(mParent);    }    mVIEwPager = (VIEwPager) convertVIEw;    if (mBanners != null && !mBanners.isEmpty()) {        if (mPagerAdapter == null) {            FragmentManager childFM = mFragment.getChildFragmentManager();            removeoldFragment(childFM);            mPagerAdapter = new ScreenSlIDePagerAdapter(childFM, mBanners);            mVIEwPager.setAdapter(mPagerAdapter);        }    }    return convertVIEw;}

关键方法:

@H_301_11@    private voID removeoldFragment(FragmentManager fm) {        try {            FIEld added = fm.getClass().getDeclaredFIEld("mAdded");            added.setAccessible(true);            added.set(fm, null);        } catch (NoSuchFIEldException e) {            throw new RuntimeException(e);        } catch (illegalaccessexception e) {            throw new RuntimeException(e);        }        try {            FIEld active = fm.getClass().getDeclaredFIEld("mActive");            active.setAccessible(true);            active.set(fm, null);        } catch (NoSuchFIEldException e) {            throw new RuntimeException(e);        } catch (illegalaccessexception e) {            throw new RuntimeException(e);        }    }
总结

以上是内存溢出为你收集整理的android – IllegalArgumentException:找不到用于片段的id的视图 – ViewPager中的ViewPager全部内容,希望文章能够帮你解决android – IllegalArgumentException:找不到用于片段的id的视图 – ViewPager中的ViewPager所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1102233.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-28
下一篇2022-05-28

发表评论

登录后才能评论

评论列表(0条)

    保存