android viewpager更改适配器

时间:2012-10-08 14:16:22

标签: android adapter android-viewpager

我正在使用ViewPager开发一个用于横向滚动表的应用程序,有时我需要更改适配器以加载一组不同的表。 我试图做以下事情:

mViewPager.setAdapter(new pagerAdapterPushed(getSupportFragmentManager()));
mViewPager.getAdapter().notifyDataSetChanged();
indicator.setViewPager(mViewPager);
indicator.invalidate();
mViewPager.invalidate();

但它总是重新加载以前的数据。是不是可以更改ViewPager的适配器?

7 个答案:

答案 0 :(得分:31)

完全像我的APP在做......

对于更改ViewPagerAdapter,我所做的是:

  1. 清除当前适配器中的所有片段
  2. 将当前适配器设置为空
  3. 为ViewPager分配新的adpater

    /* Clear all Fragments inside current adapter */
    public class MyPagerAdapter extends FragmentPagerAdapter
    {
      private ArrayList<Fragment> fragments=new ArrayList<Fragment>();
      //...some stuff
    
      public void clearAll() //Clear all page
      {
        for(int i=0; i<fragments.size(); i++)
        fragMan.beginTransaction().remove(fragments.get(i)).commit();
        fragments.clear();
      }
    }
    
    /* Set current adapter to null */
    Constants.VP.removeAllViews();
    Constants.VP.setAdapter(null);
    
    /* Assign new adpater for ViewPager */
    Constants.PAGER=new MyewPagerAdapter(getSupportFragmentManager());
    Constants.VP.setAdapter(Constants.PAGER);
    
  4. 希望有所帮助〜

答案 1 :(得分:2)

您需要覆盖寻呼机适配器中的public int getItemPosition (Object object)。对于viewpager中的每个元素,您需要返回POSITION_UNCHANGED(如果它仍在寻呼机中)或POSITION_NONE(如果它已被删除)。否则视图寻呼机将不知道某些内容已发生变化。我不建议设置新的适配器,只是清除旧的适配器。

答案 2 :(得分:1)

我看到@RRTW方式对某些人有用,但是对我来说却没有成功(尽管很接近)。如果没有'commitNow()'而不是常规的'commit()',它将无法正常工作。我做了这样的事情:

    private fun changePagerAdapter(newAdapter: PagerAdapter) {
    val transaction = supportFragmentManager.beginTransaction()
    supportFragmentManager.fragments.forEach {
        transaction.remove(it)
    }
    transaction.commitNow()
    view_pager.adapter = newAdapter
}

答案 3 :(得分:0)

对于那些仍然有问题的人,请像我所做的那样做。我希望它能节省你的时间。它在 Xamarin.Android 中,但想法在 java 和 kotlin 中应该相同

通过抽象类使用 ClearFragments 方法准备您的适配器类:

public abstract class BaseAdapter : FragmentStateAdapter
{
    public BaseAdapter(FragmentManager fm, Lifecycle lifecycle) : base(fm, lifecycle)
    {
        this.fm = fm;
    }
    readonly FragmentManager fm;
    
    public override int ItemCount => ITEM_COUNT;

    private readonly List<Fragment> fragments = new List<Fragment>();
    
    
    public override Fragment CreateFragment(int position)
    {
        var fragment = new MyFragment();
        fragments.Add(fragment);
        return fragment;
    }
    
    public void ClearFragments()
    {
        if (fragments.Count > 0)
        {
            var transaction = fm.BeginTransaction();
            foreach (var fragment in fragments)
            {
                transaction.Remove(fragment);
            }
            if (!fm.IsDestroyed)
            {
                transaction.CommitNow();
            }
            //see note of Dispose(disposing)
            foreach (var fragment in fragments)
            {
                fragment.Dispose();
            }
            fragments.Clear();
        }
    }
    
    private bool disposedValue = false;
    
    //Important note: Your fragment might use Context. You need to override Dispose(disposing) in your fragment class
    //and ensure you do not use Context after you dispose it here
    protected override void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            disposedValue = true;
            if (disposing)
            {
                ClearFragments();
            }
            base.Dispose(disposing);
        }
    }
}

public Adapter1 : BaseAdapter
{
    public Adapter1(FragmentManager fm, Lifecycle lifecycle) : base(fm, lifecycle)
    {
        
    }
}

public Adapter2 : BaseAdapter
{
    public Adapter2(FragmentManager fm, Lifecycle lifecycle) : base(fm, lifecycle)
    {
        
    }
}

然后当你想更换适配器时,这样做:

public MainActivity : AppCompatActivity
{
    private void UseAdapter2()
    {
        var oldAdapter = viewPager.Adapter as BaseAdapter;
        oldAdapter?.ClearFragments();
        viewPager.Adapter = null;
        var adapter = new Adapter2(SupportFragmentManager, Lifecycle);
        // Do any logic that makes this adapter different from the previous one.
        viewPager.Adapter = adapter;
        oldAdapter?.Dispose();
    }
}

答案 4 :(得分:0)

@易卜拉欣 您的建议与 ViewPager2 文档的建议背道而驰。它特别声明不要对 CreateFragment 使用该技术。您必须始终返回片段的新实例。不要从片段列表中重用。 见https://developer.android.com/training/animation/vp2-migration

答案 5 :(得分:-2)

我找到了一个非常简单的选项,我不知道它是对还是错,但你可以重新设置适配器

mViewPager.setAdapter(mSectionsPagerAdapter);

这是按钮 FloatingActionButton

的谷歌示例项目选项卡式活动的示例

答案 6 :(得分:-4)

将此添加到视图寻呼机以重新加载下一个片段:

viewPager.setCurrentItem()