我正在使用ViewPager开发一个用于横向滚动表的应用程序,有时我需要更改适配器以加载一组不同的表。 我试图做以下事情:
mViewPager.setAdapter(new pagerAdapterPushed(getSupportFragmentManager()));
mViewPager.getAdapter().notifyDataSetChanged();
indicator.setViewPager(mViewPager);
indicator.invalidate();
mViewPager.invalidate();
但它总是重新加载以前的数据。是不是可以更改ViewPager的适配器?
答案 0 :(得分:31)
完全像我的APP在做......
对于更改ViewPagerAdapter,我所做的是:
为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);
希望有所帮助〜
答案 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()