Viewpager片段在第一次之后未显示

Iva*_*ono 26 android android-fragments android-viewpager

我有3个片段(A,B,C)的活动.片段A由a ViewPager和2组成ListFragments.用户可以点击任何listfragments中的项目,然后执行此操作,转到片段B.

在片段AI做:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    pagerAdapter = new PagerAdapter(getActivity().getSupportFragmentManager());
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragmentA, container, false);

    vpPager = (ViewPager)view.findViewById(R.id.vpPager);
    vpPager.setOffscreenPageLimit(2);
    vpPager.setAdapter(pagerAdapter);
    vpPager.addOnPageChangeListener(this);

    return view;
}
Run Code Online (Sandbox Code Playgroud)

以下PagerAdapter是:

private class PagerAdapter extends FragmentPagerAdapter {
    private final ListFragment1 lf1 = ListFragment1 .newInstance();
    private final ListFragment2 lf2 = ListFragment2 .newInstance();

    public PagerAdapter(android.support.v4.app.FragmentManager fm) {
        super(fm);
    }

    @Override
    public android.support.v4.app.Fragment getItem(int position) {
        switch (position) {
            case 0:  return lf1;
            case 1:  return lf2;
            default: return null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

第一次显示活动时,将正确显示viewpager列表片段.

2个viewpager片段从db加载数据,我只做一次(创建片段时).

用户可以点击项目并显示片段B. 如果用户按下Back,则显示片段A. 但是未显示列表片段(已经存在它们的实例).

可能是视图已被破坏,即使存在实例?

这有什么不对?有更好的方法吗?

编辑

如果我newInstance在寻呼机适配器中使用,我会得到一个IllegalStateException: not attached to activity.这是因为我按如下方式启动异步任务:

@Override
public void onPageSelected(int position) {
    Fragment fragment = pagerAdapter.getItem(position);
    if (fragment instanceof IPagedFragment) {
        ((IPagedFragment) fragment).onShown();
    }
}
Run Code Online (Sandbox Code Playgroud)

并且onShown是:

@Override
public void onShown() {
    myTask= new MyTask();
    myTask.execute((Void)null);
}
Run Code Online (Sandbox Code Playgroud)

我何时可以启动任务,以便我可以100%确定片段已附加到活动并且视图已创建(我需要从布局中获取listview等).

Dar*_*try 93

你必须使用ChildFragmentManager如下.

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    pagerAdapter = new PagerAdapter(getChildFragmentManager()); //here used child fragment manager 
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragmentA, container, false);

    vpPager = (ViewPager)view.findViewById(R.id.vpPager);
    vpPager.setOffscreenPageLimit(2);
    vpPager.setAdapter(pagerAdapter);
    vpPager.addOnPageChangeListener(this);

    return view;
}
Run Code Online (Sandbox Code Playgroud)

它在我的代码中使用viewpager和fragment就像魅力一样.

  • 为什么getFragmentManager()只在第一次工作,而getChildFragmentManager()只工作一次的原因是什么? (2认同)

Gau*_*mar 27

刚才我在奋斗了一整天之后解决了它,getChildFragmentManager() 把它作为参数传递给了pagerAdapter.它会起作用.

在片段使用中使用pagerAdapter:

PagerAdapter adapter = new PagerAdapter(getChildFragmentManager());
Run Code Online (Sandbox Code Playgroud)

并且在活动的情况下使用getFragmentManager()

PagerAdapter adapter = new PagerAdapter(getFragmentManager());
Run Code Online (Sandbox Code Playgroud)


Mim*_*oli 15

您正在使用Activity FragmentManager创建ListFragment1和ListFragment2,而您应该使用Fragment FragmentManager.因此,修改pagerAdapter = new PagerAdapter(getActivity().getSupportFragmentManager());pagerAdapter = new PagerAdapter(getChildFragmentManager());.通过这种方式,视图寻呼机的片段将"绑定"到托管viewpager的片段.此外,您不应该在viewpager中保留对片段的任何引用:这是Android已经管理的内容.试试:

private class PagerAdapter extends FragmentPagerAdapter {

    public PagerAdapter(android.support.v4.app.FragmentManager fm) {
        super(fm);
    }

    @Override
    public android.support.v4.app.Fragment getItem(int position) {
        switch (position) {
            case 0:  return ListFragment1.newInstance();
            case 1:  return ListFragment2.newInstance();
            default: return null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,vpPager.setOffscreenPageLimit(2);因为你只有2页,所以这是一个无用的方法,这是一种我从未使用的方法,即使我有很多片段需要管理,因为它需要内存.

关于您的更新:删除与处理片段的ViewPager相关的任何逻辑.如果需要在Fragment中启动AsyncTask,可以使用Fragment生命周期的一种方法:onResume(),onCreateView()等.

class IPagedFragment extends Fragment {

    public void onResume() {
        super.onResume();
        myTask= new MyTask();
        myTask.execute((Void)null);
    }
}
Run Code Online (Sandbox Code Playgroud)

请取消private final ListFragment1 lf1 = ListFragment1 .newInstance();.相信我,这不是一个好主意,因为你有很强的参考你的碎片.

我已经构建了一个可以用作参考实现的简单项目.您可以从我的保管箱下载源代码.


Dus*_*Dus -3

  1. 在 PagerAdapter 类上重写方法setPrimaryItem,当寻呼机发生更改时会调用该方法,我会尝试一下。

我会创建类似的东西:

 private class PagerAdapter extends FragmentPagerAdapter {
        private final ListFragment1 lf1 = ListFragment1 .newInstance();
        private final ListFragment2 lf2 = ListFragment2 .newInstance();

        public PagerAdapter(android.support.v4.app.FragmentManager fm) {
            super(fm);
        }

        @Override
        public android.support.v4.app.Fragment getItem(int position) {
            switch (position) {
                case 0:  return lf1;
                case 1:  return lf2;
                default: return null;
            }
        }

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

        @Override
        public void setPrimaryItem(ViewGroup container, int position, Object object) {
            super.setPrimaryItem(container, position, object);
            if (position == 0)
                lf1.updateUI(); //Refresh what you need on this fragment
            else if (position == 1)
                lf2.updateUI();
        }

    }
Run Code Online (Sandbox Code Playgroud)
  1. getCount()也失踪了。
  2. 我不确定离屏有什么用处,但这可能不是问题。vpPager.setOffscreenPageLimit(2)
  3. 还有一件事,我也会删除vpPager.addOnPageChangeListener(this),这没有用,它可能会给你带来一些问题。无论你需要做什么,你都可以在没有它的情况下完成它,通过覆盖分页,你可能会“破坏”一些标准分页(因为没有调用 super )

  • 我只是遵循他的设计并指出改进它的方法,你也可以这样做,而不是抨击.. (3认同)