为了账号安全,请及时绑定邮箱和手机立即绑定

替换ViewPager中的片段

替换ViewPager中的片段

蝴蝶不菲 2019-06-14 09:55:00
替换ViewPager中的片段我试着用片段ViewPager使用FragmentPagerAdapter..我想要实现的是替换位于ViewPager和另一个。寻呼机由两页组成。第一个是FirstPagerFragment,第二个是SecondPagerFragment..单击第一页的按钮。我想替换一下FirstPagerFragment与下一帧。下面是我的代码。public class FragmentPagerActivity extends FragmentActivity {     static final int NUM_ITEMS = 2;     MyAdapter mAdapter;     ViewPager mPager;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.fragment_pager);         mAdapter = new MyAdapter(getSupportFragmentManager());         mPager = (ViewPager) findViewById(R.id.pager);         mPager.setAdapter(mAdapter);     }     /**      * Pager Adapter      */     public static class MyAdapter extends FragmentPagerAdapter {         public MyAdapter(FragmentManager fm) {             super(fm);         }         @Override         public int getCount() {             return NUM_ITEMS;         }         @Override         public Fragment getItem(int position) {             if(position == 0) {                 return FirstPageFragment.newInstance();             } else {                 return SecondPageFragment.newInstance();             }         }     }     /**      * Second Page FRAGMENT      */     public static class SecondPageFragment extends Fragment {         public static SecondPageFragment newInstance() {             SecondPageFragment f = new SecondPageFragment();             return f;         }         @Override         public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {             //Log.d("DEBUG", "onCreateView");             return inflater.inflate(R.layout.second, container, false);         }     }          现在问题是.。我应该在哪个ID中使用?trans.replace(R.id.first_fragment_root_id, NextFragment.newInstance());?
查看完整描述

3 回答

?
白板的微信

TA贡献1883条经验 获得超3个赞

还有另一种解决方案,不需要修改ViewPagerFragmentStatePagerAdapter,它与FragmentPagerAdapter作者使用的基类。

首先,我想回答作者关于他应该使用哪个ID的问题;它是容器的ID,即视图寻呼机本身的ID。但是,正如您自己可能注意到的那样,在代码中使用ID不会导致任何事情发生。我会解释原因:

首先,让ViewPager重新填充页面,您需要调用notifyDataSetChanged()它驻留在适配器的基类中。

第二,ViewPager使用getItemPosition()检查哪些页应该销毁,哪些页应该保存的抽象方法。此函数的默认实现总是返回POSITION_UNCHANGED,这会导致ViewPager保留所有当前页,因此不附加新页。因此,为了使碎片替换工作,getItemPosition()需要在适配器中重写,并且必须返回。POSITION_NONE当用一个旧的,被隐藏的,片段作为参数调用时。

这也意味着您的适配器总是需要知道哪个片段应该显示在第0位置,FirstPageFragmentNextFragment..这样做的一种方法是在创建FirstPageFragment,当切换片段的时候将被调用。我认为这是一件好事,让您的片段适配器处理所有片段开关和调用ViewPagerFragmentManager.

第三,FragmentPagerAdapter用从位置派生的名称缓存使用的片段,因此如果在0位置有一个片段,即使类是新的,也不会替换它。有两个解决方案,但最简单的是使用remove()功能FragmentTransaction,这也会移除它的标签。

这是大量的文本,下面是在您的情况下应该工作的代码:

public class MyAdapter extends FragmentPagerAdapter{
    static final int NUM_ITEMS = 2;
    private final FragmentManager mFragmentManager;
    private Fragment mFragmentAtPos0;

    public MyAdapter(FragmentManager fm)
    {
        super(fm);
        mFragmentManager = fm;
    }

    @Override
    public Fragment getItem(int position)
    {
        if (position == 0)
        {
            if (mFragmentAtPos0 == null)
            {
                mFragmentAtPos0 = FirstPageFragment.newInstance(new FirstPageFragmentListener()
                {
                    public void onSwitchToNextFragment()
                    {
                        mFragmentManager.beginTransaction().remove(mFragmentAtPos0).commit();
                        mFragmentAtPos0 = NextFragment.newInstance();
                        notifyDataSetChanged();
                    }
                });
            }
            return mFragmentAtPos0;
        }
        else
            return SecondPageFragment.newInstance();
    }

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

    @Override
    public int getItemPosition(Object object)
    {
        if (object instanceof FirstPageFragment && mFragmentAtPos0 instanceof NextFragment)
            return POSITION_NONE;
        return POSITION_UNCHANGED;
    }}public interface FirstPageFragmentListener{
    void onSwitchToNextFragment();}

希望这能帮到任何人!


查看完整回答
反对 回复 2019-06-14
?
www说

TA贡献1775条经验 获得超8个赞

我觉得这是有帮助和优雅的,我可以部分地实现我想要的东西,因为我希望cability回到第一个片段(一旦被替换),我完成了对他代码的一点修改。

这将是FragmentPagerAdapter:

public static class MyAdapter extends FragmentPagerAdapter {
    private final class CalendarPageListener implements
            CalendarPageFragmentListener {
        public void onSwitchToNextFragment() {
            mFragmentManager.beginTransaction().remove(mFragmentAtPos0)
                    .commit();
            if (mFragmentAtPos0 instanceof FirstFragment){
                mFragmentAtPos0 = NextFragment.newInstance(listener);
            }else{ // Instance of NextFragment
                mFragmentAtPos0 = FirstFragment.newInstance(listener);
            }
            notifyDataSetChanged();
        }
    }

    CalendarPageListener listener = new CalendarPageListener();;
    private Fragment mFragmentAtPos0;
    private FragmentManager mFragmentManager;

    public MyAdapter(FragmentManager fm) {
        super(fm);
        mFragmentManager = fm;
    }

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

    @Override
    public int getItemPosition(Object object) {
        if (object instanceof FirstFragment && mFragmentAtPos0 instanceof NextFragment)
            return POSITION_NONE;
        if (object instanceof NextFragment && mFragmentAtPos0 instanceof FirstFragment)
            return POSITION_NONE;
        return POSITION_UNCHANGED;
    }

    @Override
    public Fragment getItem(int position) {
        if (position == 0)
            return Portada.newInstance();
        if (position == 1) { // Position where you want to replace fragments
            if (mFragmentAtPos0 == null) {
                mFragmentAtPos0 = FirstFragment.newInstance(listener);
            }
            return mFragmentAtPos0;
        }
        if (position == 2)
            return Clasificacion.newInstance();
        if (position == 3)
            return Informacion.newInstance();

        return null;
    }}public interface CalendarPageFragmentListener {
    void onSwitchToNextFragment();}

若要执行替换,只需定义类型的静态字段。CalendarPageFragmentListener并通过newInstance方法的相应片段和调用FirstFragment.pageListener.onSwitchToNextFragment()NextFragment.pageListener.onSwitchToNextFragment()临时的。


查看完整回答
反对 回复 2019-06-14
  • 3 回答
  • 0 关注
  • 431 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信