【问题标题】:ViewPager Fragments are not initiated in onCreateViewPager Fragments 未在 onCreate 中启动
【发布时间】:2014-04-10 19:24:25
【问题描述】:

无论我尝试使用 onCreate()、onCreateView() 还是 onResume(),我似乎在更新我在 ViewPager 中使用的片段时遇到问题。以下是我在 MainFragment 中设置 ViewPager 的方式:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       View rootView = inflater.inflate(R.layout.fragment_main_screen, container, false);

        mPager = (ViewPager)rootView.findViewById(R.id.pager);
        mPager.setOffscreenPageLimit(2); // So all 3 pages are loaded at once.
        mAdapter = new JournalPagerAdapter(getActivity().getSupportFragmentManager(), this);
        mPager.setAdapter(mAdapter);

        // Add bar graph to view
        mGraphLayout = (LinearLayout) rootView.findViewById(R.id.journalGraph);
        updateGraph();
        mGraphLayout.addView(mGraphView);

        mPainFrag = (PainFragment)mAdapter.getRegisteredFragment(0);
        // Null pointer here, but if I put the action in a button listener, it works.
        mPainFrag.setScale(mEntry.getPain());
...

我正在通过 FragmentPagerAdapter 中的一些覆盖方法访问片段:

public class JournalPagerAdapter extends FragmentPagerAdapter {

    SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
    private View.OnClickListener mOnClickListener;


    public JournalPagerAdapter(FragmentManager mgr, View.OnClickListener onClickListener) {
        super(mgr);
        mOnClickListener = onClickListener;
    }
    @Override
    public Fragment getItem(int pos) {
        switch(pos) {

            case 0: return PainFragment.newInstance("PainFragment", mOnClickListener);
            case 1: return StressFragment.newInstance("StressFragment", mOnClickListener);
            case 2: return SleepFragment.newInstance("SleepFragment", mOnClickListener);
            default: return PainFragment.newInstance("PainFragment", mOnClickListener);
        }
    }

    @Override
    public int getCount() {
        return 3;
    }

    /* Thanks to Streets of Boston (http://stackoverflow.com/questions/8785221/retrieve-a-fragment-from-a-viewpager)
    */

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Log.v("rx", "itemInstantiated");
        Fragment fragment = (Fragment) super.instantiateItem(container, position);
        registeredFragments.put(position, fragment);
        return fragment;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        registeredFragments.remove(position);
        super.destroyItem(container, position, object);
    }

    public Fragment getRegisteredFragment(int position) {
        return registeredFragments.get(position);
    }

在设置适配器后,我似乎无法弄清楚为什么片段为空,但如果我将片段更新代码放在点击事件中,我没有问题。

【问题讨论】:

  • 您是否尝试制作一个 Runnable 以让 ui 有时间创建 ViewPager?
  • 我在最初的实验中考虑过这一点,但我宁愿使用 runnable 作为最后的手段。我不认为我在这里做任何不寻常的事情,这听起来合乎逻辑,有一种方法可以通知 FragmentPagerAdapter 正在完全初始化的主机片段。
  • 我认为您没有选择余地,因为您使用 mAdapter.getRegisteredFragment 选择了片段(它是您的适配器的内部方法)。那么,我认为你必须等待适配器。
  • 你的第一个片段没有启动,那么第二个片段呢?
  • @jwburnside你说如果我把framgent更新代码放在点击事件中,你的更新代码在哪里开始?

标签: android android-fragments android-viewpager


【解决方案1】:

我会尝试向您的 ViewPager 添加一个布局侦听器,以便在视图布局发生时得到通知。

当您创建 ViewPager 调用 mPager.getViewTreeObserver().addOnGlobalLayoutListener() 并传递实现 OnGlobalLayoutListener 的内容时。

在回调方法中,进行片段更新。一定要在回调中调用mPager.getViewTreeObserver().removeGlobalOnLayoutListener(this),否则回调会被多次调用。

【讨论】:

    【解决方案2】:

    您可以在PagerAdapter 的构造函数中实例化您的片段,然后让getItem 返回它们而不是实例化它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-29
      • 1970-01-01
      • 1970-01-01
      • 2015-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多