【问题标题】:android viewpager change adapterandroid viewpager 更改适配器
【发布时间】:2012-10-08 14:16:22
【问题描述】:

我正在为横向滚动表格开发一个带有 ViewPager 的应用程序,有时我需要更改适配器以加载一组不同的表格。 我已尝试执行以下操作:

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

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

【问题讨论】:

    标签: android adapter android-viewpager


    【解决方案1】:

    和我的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 MyPagerAdapter(getSupportFragmentManager());
      Constants.VP.setAdapter(Constants.PAGER);
      

    希望对你有帮助~

    【讨论】:

    • 我尝试了您的解决方案。它工作完美,没有任何问题。非常感谢
    • 在 API 18 中我不能setAdapter(null)。然而,其他一切都奏效了。谢谢。
    • 非常感谢!我已经找了好几天了!
    • 对我来说,唯一必要的部分是使用片段管理器事务删除片段。其余的都是不必要的(即 removeAllViews、setAdapter(null) 等)。
    • 由于某种原因,这仅在我将其从 FragmentPagerAdapter 更改为 FragmentStatePagerAdapter 后才对我有用
    【解决方案2】:

    您需要覆盖寻呼机适配器中的public int getItemPosition (Object object)。对于视图分页器中的每个元素,您需要返回POSITION_UNCHANGED(如果它仍在分页器中)或POSITION_NONE(如果它已被删除)。否则视图寻呼机不会知道有什么变化。我不建议设置新适配器,只需清除旧适配器中的数据即可。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        对于那些仍然有问题的人,像我一样做。我希望它能节省你的时间。它在 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();
            }
        }
        

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

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

            viewPager.setCurrentItem()
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-05-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-10-27
              • 1970-01-01
              • 2016-11-25
              • 1970-01-01
              相关资源
              最近更新 更多