631

我正在使用兼容性库中的 ViewPager。我已经成功地让它显示了几个可以翻页的视图。

但是,我很难弄清楚如何用一组新的视图更新 ViewPager。

我已经尝试了各种方法,例如 call mAdapter.notifyDataSetChanged()mViewPager.invalidate()甚至每次我想使用新的数据列表时都创建一个全新的适配器。

没有任何帮助,文本视图与原始数据保持不变。

更新: 我做了一个小测试项目,我几乎能够更新视图。我将粘贴下面的课程。

然而,似乎没有更新的是第二个视图,“B”仍然存在,按下更新按钮后它应该显示“Y”。

public class ViewPagerBugActivity extends Activity {

    private ViewPager myViewPager;
    private List<String> data;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        data = new ArrayList<String>();
        data.add("A");
        data.add("B");
        data.add("C");

        myViewPager = (ViewPager) findViewById(R.id.my_view_pager);
        myViewPager.setAdapter(new MyViewPagerAdapter(this, data));

        Button updateButton = (Button) findViewById(R.id.update_button);
        updateButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                updateViewPager();
            }
        });
    }

    private void updateViewPager() {
        data.clear();
        data.add("X");
        data.add("Y");
        data.add("Z");
        myViewPager.getAdapter().notifyDataSetChanged();
    }

    private class MyViewPagerAdapter extends PagerAdapter {

        private List<String> data;
        private Context ctx;

        public MyViewPagerAdapter(Context ctx, List<String> data) {
            this.ctx = ctx;
            this.data = data;
        }

        @Override
        public int getCount() {
            return data.size();
        }

        @Override
        public Object instantiateItem(View collection, int position) {
            TextView view = new TextView(ctx);
            view.setText(data.get(position));
            ((ViewPager)collection).addView(view);
            return view;
        }

        @Override
        public void destroyItem(View collection, int position, Object view) {
             ((ViewPager) collection).removeView((View) view);
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Parcelable saveState() {
            return null;
        }

        @Override
        public void restoreState(Parcelable arg0, ClassLoader arg1) {
        }

        @Override
        public void startUpdate(View arg0) {
        }

        @Override
        public void finishUpdate(View arg0) {
        }
    }
}
4

42 回答 42

896

有几种方法可以实现这一点。

第一种选择更容易,但效率更低。

像这样覆盖getItemPositionPagerAdapter

public int getItemPosition(Object object) {
    return POSITION_NONE;
}

这样,当您调用 时notifyDataSetChanged(),视图寻呼机将删除所有视图并重新加载它们。这样就获得了重装效果。

第二个选项,由 Alvaro Luis Bustamante (previously alvarolb) 建议,是在实例化新视图时使用setTag()方法。instantiateItem()然后notifyDataSetChanged(),您可以使用findViewWithTag()来查找要更新的视图,而不是使用。

第二种方法非常灵活和高性能。感谢 alvarolb 的原创研究。

于 2011-09-02T17:28:20.010 回答
494

我不认为PagerAdapter. 问题是理解它的工作原理有点复杂。查看此处解释的解决方案,存在误解,因此从我的角度来看,实例化视图的使用不当。

最近几天我一直在使用PagerAdapterand ViewPager,我发现了以下内容:

上的notifyDataSetChanged()方法PagerAdapter只会通知ViewPager底层页面已更改。例如,如果您已动态创建/删除页面(从列表中添加或删除项目),则ViewPager应该注意这一点。在这种情况下,我认为ViewPager确定是否应该使用getItemPosition()andgetCount()方法删除或实例化新视图。

我认为ViewPager,在一个notifyDataSetChanged()电话之后,它的子视图和检查他们的位置getItemPosition()。如果对于子视图,此方法返回POSITION_NONE,则ViewPager了解该视图已被删除,调用destroyItem()并删除此视图。

这样一来,如果你只想更新页面的内容,重写getItemPosition()总是返回是完全错误的,因为之前创建的视图会被销毁,每次调用都会创建新的视图。仅仅几秒钟似乎并没有那么错,但是当您有复杂的视图时,例如从数据库填充的 ListViews,这可能是一个真正的问题并且浪费资源。POSITION_NONEnotifyDatasetChanged()TextView

因此,有几种方法可以有效地更改视图的内容,而无需再次删除和实例化视图。这取决于您要解决的问题。我的方法是对该setTag()方法中的任何实例化视图使用该instantiateItem()方法。因此,当您想要更改数据或使所需的视图无效时,您可以调用 上的findViewWithTag()方法ViewPager来检索先前实例化的视图并根据需要修改/使用它,而无需每次都删除/创建新视图更新一些值。

例如,假设您有 100 个页面和 100TextView秒,并且您只想定期更新一个值。使用前面解释的方法,这意味着您将TextView在每次更新时删除和实例化 100 秒。它没有任何意义...

于 2011-11-06T01:11:17.820 回答
91

将 更改FragmentPagerAdapterFragmentStatePagerAdapter

覆盖getItemPosition()方法并返回POSITION_NONE

最终,它将收听notifyDataSetChanged()on view 寻呼机。

于 2014-09-05T02:07:50.083 回答
48

alvarolb 给出的答案绝对是最好的方法。基于他的回答,实现这一点的一种简单方法是简单地按位置存储活动视图:

SparseArray<View> views = new SparseArray<View>();

@Override
public Object instantiateItem(View container, int position) {
    View root = <build your view here>;
    ((ViewPager) container).addView(root);
    views.put(position, root);
    return root;
}

@Override
public void destroyItem(View collection, int position, Object o) {
    View view = (View)o;
    ((ViewPager) collection).removeView(view);
    views.remove(position);
    view = null;
}

然后通过覆盖该notifyDataSetChanged方法一次,您可以刷新视图...

@Override
public void notifyDataSetChanged() {
    int key = 0;
    for(int i = 0; i < views.size(); i++) {
       key = views.keyAt(i);
       View view = views.get(key);
       <refresh view with new data>
    }
    super.notifyDataSetChanged();
}

您实际上可以在instantiateItemnotifyDataSetChanged刷新视图中使用类似的代码。在我的代码中,我使用完全相同的方法。

于 2012-06-06T01:55:52.447 回答
32

有同样的问题。对我来说,它可以扩展 FragmentStatePagerAdapter,并覆盖以下方法:

@Override
public Parcelable saveState() {
    return null;
}

@Override
public void restoreState(Parcelable state, ClassLoader loader) {

}
于 2015-06-17T07:57:37.280 回答
21

经过数小时的挫折,同时尝试了所有上述解决方案来克服这个问题,并尝试了许多其他类似问题的解决方案,比如这个这个这个都失败了,我无法解决这个问题并ViewPager破坏旧的并Fragment填充pagerFragments。我已经解决了以下问题:

1)使ViewPager类扩展FragmentPagerAdapter如下:

 public class myPagerAdapter extends FragmentPagerAdapter {

2)ViewPager为该商店创建一个项目,title如下fragment所示:

public class PagerItem {
private String mTitle;
private Fragment mFragment;


public PagerItem(String mTitle, Fragment mFragment) {
    this.mTitle = mTitle;
    this.mFragment = mFragment;
}
public String getTitle() {
    return mTitle;
}
public Fragment getFragment() {
    return mFragment;
}
public void setTitle(String mTitle) {
    this.mTitle = mTitle;
}

public void setFragment(Fragment mFragment) {
    this.mFragment = mFragment;
}

}

3)使ViewPagertake myFragmentManager实例的构造函数将其存储在myclass中,如下所示:

private FragmentManager mFragmentManager;
private ArrayList<PagerItem> mPagerItems;

public MyPagerAdapter(FragmentManager fragmentManager, ArrayList<PagerItem> pagerItems) {
    super(fragmentManager);
    mFragmentManager = fragmentManager;
    mPagerItems = pagerItems;
}

4)创建一个方法来用新数据重新设置adapter数据,方法是直接fragmentfragmentManager自身中删除所有以前的数据,以便再次从新列表adapter中设置新数据fragment,如下所示:

public void setPagerItems(ArrayList<PagerItem> pagerItems) {
    if (mPagerItems != null)
        for (int i = 0; i < mPagerItems.size(); i++) {
            mFragmentManager.beginTransaction().remove(mPagerItems.get(i).getFragment()).commit();
        }
    mPagerItems = pagerItems;
}

5)从容器ActivityFragment不使用新数据重新初始化适配器。通过使用新数据的方法设置setPagerItems新数据如下:

ArrayList<PagerItem> pagerItems = new ArrayList<PagerItem>();
pagerItems.add(new PagerItem("Fragment1", new MyFragment1()));
pagerItems.add(new PagerItem("Fragment2", new MyFragment2()));

mPagerAdapter.setPagerItems(pagerItems);
mPagerAdapter.notifyDataSetChanged();

我希望它有所帮助。

于 2014-03-08T18:01:15.390 回答
9

我有同样的问题,我的解决方案是使用FragmentPagerAdapter覆盖FragmentPagerAdapter#getItemId(int position)

@Override
public long getItemId(int position) {
    return mPages.get(position).getId();
}

默认情况下,此方法返回项目的位置。我想ViewPager检查是否itemId已更改并仅在更改页面时才重新创建页面。itemId但是即使页面实际上不同,未覆盖的版本也会返回相同的位置,并且 ViewPager 没有定义该页面被替换为一个并且需要重新创建。

要使用它,long id每个页面都需要。通常它应该是唯一的,但我建议,对于这种情况,它应该与同一页面的先前值不同。因此,可以在这里使用适配器中的连续计数器或随机整数(分布广泛)。

我认为这是更一致的方式,而不是使用提到的视图标签作为本主题中的解决方案。但可能并非适用于所有情况。

于 2017-05-25T10:02:53.953 回答
7

我发现这个问题的决定非常有趣。我们可以使用FragmentStatePagerAdapter ( android.support.v4.app.FragmentStatePagerAdapter ),而不是使用FragmentPagerAdapter将所有片段保存在内存中,当我们选择它时,它每次都重新加载片段。

两个适配器的实现是相同的。所以,我们只需要在“ extend FragmentStatePagerAdapter ”上更改“extend FragmentPagerAdapter

于 2017-02-01T13:23:08.547 回答
6

所有这些解决方案都没有帮助我。因此我找到了一个可行的解决方案:您setAdapter每次都可以,但这还不够。您应该在更改适配器之前执行这些操作:

FragmentManager fragmentManager = slideShowPagerAdapter.getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
List<Fragment> fragments = fragmentManager.getFragments();
for (Fragment f : fragments) {
    transaction.remove(f);
}
transaction.commit();

在此之后:

viewPager.setAdapter(adapter);
于 2014-02-04T11:34:55.113 回答
6

ViewPager 不是为支持动态视图更改而设计的。

我在寻找与此相关的另一个错误时确认了这一点https://issuetracker.google.com/issues/36956111尤其是https://issuetracker.google.com/issues/36956111#comment56

这个问题有点老了,但谷歌最近用ViewPager2解决了这个问题。它将允许用标准解决方案替换手工制作的(未维护且可能有故障的)解决方案。它还可以防止像某些答案那样不必要地重新创建视图。

对于 ViewPager2 示例,您可以查看https://github.com/googlesamples/android-viewpager2

如果要使用 ViewPager2,则需要在 build.gradle 文件中添加以下依赖项:

  dependencies {
     implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'
  }

然后,您可以将 xml 文件中的 ViewPager 替换为:

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

之后,您需要在活动中将 ViewPager 替换为 ViewPager2

ViewPager2 需要 RecyclerView.Adapter 或 FragmentStateAdapter,在您的情况下它可以是 RecyclerView.Adapter

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    private Context context;
    private ArrayList<String> arrayList = new ArrayList<>();

    public MyAdapter(Context context, ArrayList<String> arrayList) {
        this.context = context;
        this.arrayList = arrayList;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.tvName.setText(arrayList.get(position));
    }

    @Override
    public int getItemCount() {
        return arrayList.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView tvName;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            tvName = itemView.findViewById(R.id.tvName);
        }
    }
} 

在您使用 TabLayout 的情况下,您可以使用 TabLayoutMediator :

        TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager, true, new TabLayoutMediator.OnConfigureTabCallback() {
            @Override
            public void onConfigureTab(@NotNull TabLayout.Tab tab, int position) {
                // configure your tab here
                tab.setText(tabs.get(position).getTitle());
            }
        });

        tabLayoutMediator.attach();

然后,您将能够通过修改适配器的数据并调用 notifyDataSetChanged 方法来刷新视图

于 2019-08-07T11:29:40.923 回答
5

经过大量搜索此问题后,我找到了一个非常好的解决方案,我认为这是解决此问题的正确方法。本质上,instantiateItem 仅在视图被实例化时被调用,除非视图被销毁,否则永远不会再次调用(当您覆盖 getItemPosition 函数以返回 POSITION_NONE 时会发生这种情况)。相反,您要做的是保存创建的视图并在适配器中更新它们,生成一个 get 函数以便其他人可以更新它,或者一个更新适配器的 set 函数(我最喜欢的)。

因此,在您的 MyViewPagerAdapter 添加一个变量,如:

private View updatableView;

在您的实例化项目中:

 public Object instantiateItem(View collection, int position) {
        updatableView = new TextView(ctx); //My change is here
        view.setText(data.get(position));
        ((ViewPager)collection).addView(view);
        return view;
    }

因此,通过这种方式,您可以创建一个更新视图的函数:

public updateText(String txt)
{
    ((TextView)updatableView).setText(txt);
}

希望这可以帮助!

于 2011-11-30T20:43:03.657 回答
5

一种更简单的方法:使用FragmentPagerAdapter, 并将分页视图包装到片段上。他们确实得到了更新

于 2012-11-14T22:08:35.397 回答
5

OP 提出问题两年半后,这个问题仍然是,嗯,仍然是一个问题。很明显,谷歌在这方面的优先级并不是特别高,所以我没有找到解决办法,而是找到了一种解决方法。对我来说,最大的突破是找出问题的真正原因是什么(请参阅这篇文章中接受的答案)。一旦问题很明显是任何活动页面都没有正确刷新,我的解决方法就很明显了:

在我的片段(页面)中:

  • 我从 onCreateView 中取出填充表单的所有代码,并将其放入一个名为 PopulateForm 的函数中,该函数可以从任何地方调用,而不是由框架调用。此函数尝试使用 getView 获取当前视图,如果为 null,则返回。重要的是 PopulateForm 仅包含显示的代码 - 创建 FocusChange 侦听器等的所有其他代码仍在 OnCreate
  • 创建一个布尔值,它可以用作指示表单必须重新加载的标志。我的是 mbReloadForm
  • 如果设置了 mbReloadForm,则覆盖 OnResume() 以调用 PopulateForm()。

在我的活动中,我在其中加载页面:

  • 在更改任何内容之前转到第 0 页。我使用的是 FragmentStatePagerAdapter,所以我知道最多有两三个页面受到影响。更改到第 0 页可确保我只在第 0、1 和 2 页遇到问题。
  • 在清除旧列表之前,先获取它的 size()。这样您就知道有多少页面受到错误的影响。如果 > 3,则将其减少到 3 - 如果您使用不同的 PagerAdapter,则必须查看必须处理的页面数(也许全部?)
  • 重新加载数据并调用 pageAdapter.notifyDataSetChanged()
  • 现在,对于每个受影响的页面,使用 pager.getChildAt(i) 查看页面是否处于活动状态 - 这会告诉您是否有视图。如果是这样,请调用 pager.PopulateView()。如果没有,请设置 ReloadForm 标志。

在此之后,当您重新加载第二组页面时,该错误仍会导致一些显示旧数据。但是,它们现在将被刷新,您将看到新数据 - 您的用户不会知道页面曾经不正确,因为刷新会在他们看到页面之前发生。

希望这对某人有帮助!

于 2014-02-07T11:08:57.537 回答
5

感谢 rui.araujo 和 Alvaro Luis Bustamante。起初,我尝试使用 rui.araujo 的方式,因为它很简单。它可以工作,但是当数据发生变化时,页面会明显重绘。这很糟糕,所以我尝试使用 Alvaro Luis Bustamante 的方式。这是完美的。这是代码:

@Override
protected void onStart() {
    super.onStart();
}

private class TabPagerAdapter extends PagerAdapter {
    @Override
    public int getCount() {
        return 4;
    }

    @Override
    public boolean isViewFromObject(final View view, final Object object) {
        return view.equals(object);
    }

    @Override
    public void destroyItem(final View container, final int position, final Object object) {
        ((ViewPager) container).removeView((View) object);
    }

    @Override
    public Object instantiateItem(final ViewGroup container, final int position) {
        final View view = LayoutInflater.from(
                getBaseContext()).inflate(R.layout.activity_approval, null, false);
        container.addView(view);
        ListView listView = (ListView) view.findViewById(R.id.list_view);
        view.setTag(position);
        new ShowContentListTask(listView, position).execute();
        return view;
    }
}

当数据发生变化时:

for (int i = 0; i < 4; i++) {
    View view = contentViewPager.findViewWithTag(i);
    if (view != null) {
        ListView listView = (ListView) view.findViewById(R.id.list_view);
        new ShowContentListTask(listView, i).execute();
    }
}
于 2016-09-28T06:46:29.400 回答
4

我只是发布这个答案,以防其他人发现它有用。为了做同样的事情,我只是从兼容性库中获取 ViewPager 和 PagerAdapter 的源代码并在我的代码中编译它(您需要整理所有错误并自己导入,但绝对可以完成)。

然后,在 CustomViewPager 中,创建一个名为 updateViewAt(int position) 的方法。视图本身可以从 ViewPager 类中定义的 ArrayList mItems 中获取(您需要在实例化项目时为视图设置一个 Id,并将此 id 与 updateViewAt() 方法中的位置进行比较)。然后,您可以根据需要更新视图。

于 2011-11-02T10:14:43.413 回答
4

我有一个类似的问题,其中我有四个页面,其中一个页面更新了其他三个页面的视图。我能够更新与当前页面相邻的页面上的小部件(SeekBars、TextViews 等)。最后两页在调用mTabsAdapter.getItem(position).

为了解决我的问题,我setSelectedPage(index)在调用之前使用了getItem(position). 这将实例化页面,使我能够更改每个页面上的值和小部件。

setSelectedPage(position)在完成所有更新后,我将使用notifyDataSetChanged().

您可以在主更新页面的 ListView 中看到轻微的闪烁,但没有明显的变化。我还没有彻底测试它,但它确实解决了我的直接问题。

于 2011-11-02T16:55:28.533 回答
4

以防万一有人使用基于FragmentStatePagerAdapter的适配器(这将使 ViewPager 创建显示所需的最少页面,我的情况最多为 2 个),@rui.araujo 的在适配器中覆盖 getItemPosition 的答案不会造成重大浪费,但它仍然可以改进。

在伪代码中:

public int getItemPosition(Object object) {
    YourFragment f = (YourFragment) object;
    YourData d = f.data;
    logger.info("validate item position on page index: " + d.pageNo);

    int dataObjIdx = this.dataPages.indexOf(d);

    if (dataObjIdx < 0 || dataObjIdx != d.pageNo) {
        logger.info("data changed, discard this fragment.");
        return POSITION_NONE;
    }

    return POSITION_UNCHANGED;
}
于 2013-07-11T05:56:38.903 回答
2

您可以动态更新所有片段,您可以分三步查看。

在您的适配器中:

public class MyPagerAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 3;
private Map<Integer, String> mFragmentTags;
private FragmentManager mFragmentManager;

public MyPagerAdapter(FragmentManager fragmentManager) {
    super(fragmentManager);
    mFragmentManager = fragmentManager;
    mFragmentTags = new HashMap<Integer, String>();
}

// Returns total number of pages
@Override
public int getCount() {
    return NUM_ITEMS;
}

// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
    switch (position) {
        case 0:
            return FirstFragment.newInstance();
        case 1:
            return SecondFragment.newInstance();
        case 2:
            return ThirdFragment.newInstance();
        default:
            return null;
    }
}

// Returns the page title for the top indicator
@Override
public CharSequence getPageTitle(int position) {
    return "Page " + position;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
    Object object = super.instantiateItem(container, position);
    if (object instanceof Fragment) {
        Fragment fragment = (Fragment) object;
        String tag = fragment.getTag();
        mFragmentTags.put(position, tag);
    }
    return object;
}

public Fragment getFragment(int position) {
    Fragment fragment = null;
    String tag = mFragmentTags.get(position);
    if (tag != null) {
        fragment = mFragmentManager.findFragmentByTag(tag);
    }
    return fragment;
}}

现在在您的活动中:

public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener{

MyPagerAdapter mAdapterViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ViewPager viewPager = (ViewPager) findViewById(R.id.vpPager);
    mAdapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(mAdapterViewPager);
    viewPager.addOnPageChangeListener(this);
}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {

    Fragment fragment = mAdapterViewPager.getFragment(position);
    if (fragment != null) {
        fragment.onResume();
    }
}

@Override
public void onPageScrollStateChanged(int state) {

}}

最后在你的片段中,类似这样的东西:

public class YourFragment extends Fragment {

// newInstance constructor for creating fragment with arguments
public static YourFragment newInstance() {

    return new YourFragment();
}

// Store instance variables based on arguments passed
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

// Inflate the view for the fragment based on layout XML
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment, container, false);
}


@Override
public void onResume() {
    super.onResume();

    //to refresh your view
    refresh();

}}

你可以在这里看到完整的代码。

感谢阿尔瓦罗·路易斯·布斯塔曼特。

于 2016-01-17T18:19:16.450 回答
2

我想,我有 ViewPager 的逻辑。

如果我需要刷新一组页面并根据新数据集显示它们,我调用notifyDataSetChanged()。然后,ViewPager 对getItemPosition()进行了多次调用,将 Fragment 作为对象传递给那里。此片段可以来自旧数据集(我想丢弃)或来自新数据集(我想显示)。所以,我覆盖了 getItemPosition()并且我必须以某种方式确定我的 Fragment 是来自旧数据集还是来自新数据集。

在我的例子中,我有一个 2 窗格布局,左侧窗格上有一个顶部项目列表,右侧有一个滑动视图 (ViewPager)。因此,我在 PagerAdapter 以及每个实例化的页面 Fragment 中存储了指向当前顶部项目的链接。当列表中选定的顶部项目发生更改时,我将新的顶部项目存储在 PagerAdapter 中并调用notifyDataSetChanged()。在覆盖的 getItemPosition()中,我将适配器中的顶部项目与片段中的顶部项目进行比较。 只有当它们不相等时,我才返回 POSITION_NONE。 然后,PagerAdapter 重新实例化所有返回 POSITION_NONE 的片段。

笔记。存储顶部项目 ID 而不是参考可能是一个更好的主意。

下面的代码片段有点示意性,但我从实际工作的代码中改编了它。

public class SomeFragment extends Fragment {
  private TopItem topItem;
}

public class SomePagerAdapter extends FragmentStatePagerAdapter {
  private TopItem topItem;

  public void changeTopItem(TopItem newTopItem) {
    topItem = newTopItem;
    notifyDataSetChanged();
  }

  @Override
  public int getItemPosition(Object object) {
    if (((SomeFragment) object).getTopItemId() != topItem.getId()) {
      return POSITION_NONE;
    }
    return super.getItemPosition(object);
  }
}

感谢所有以前的研究人员!

于 2017-02-08T17:05:01.513 回答
2

下面的代码对我有用。

创建一个扩展 FragmentPagerAdapter 类的类,如下所示。

public class Adapter extends FragmentPagerAdapter {

private int tabCount;
private Activity mActivity;
private Map<Integer, String> mFragmentTags;
private FragmentManager mFragmentManager;
private int container_id;
private ViewGroup container;
private List<Object> object;

public Adapter(FragmentManager fm) {
    super(fm);
}

public Adapter(FragmentManager fm, int numberOfTabs , Activity mA) {
    super(fm);
    mActivity = mA;
    mFragmentManager = fm;
    object = new ArrayList<>();
    mFragmentTags = new HashMap<Integer, String>();
    this.tabCount = numberOfTabs;
}

@Override
public Fragment getItem(int position) {
    switch (position) {
        case 0:
            return Fragment0.newInstance(mActivity);
        case 1:
            return Fragment1.newInstance(mActivity);
        case 2:
            return Fragment2.newInstance(mActivity);
        default:
            return null;
    }}


@Override
public Object instantiateItem(ViewGroup container, int position) {
    Object object = super.instantiateItem(container, position);
    if (object instanceof Fragment) {
        Log.e("Already defined","Yes");
        Fragment fragment = (Fragment) object;
        String tag = fragment.getTag();
        Log.e("Fragment Tag","" + position + ", " + tag);
        mFragmentTags.put(position, tag);
    }else{
        Log.e("Already defined","No");
    }
    container_id = container.getId();
    this.container = container;
    if(position == 0){
        this.object.add(0,object);
    }else if(position == 1){
        this.object.add(1,object);
    }else if(position == 2){
        this.object.add(2,object);
    }
    return object;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);
    if (object instanceof Fragment) {
        Log.e("Removed" , String.valueOf(position));
    }
}

@Override
public int getItemPosition (Object object)
{   int index = 0;
    if(this.object.get(0) == object){
        index = 0;
    }else if(this.object.get(1) == object){
        index = 1;
    }else if(this.object.get(2) == object){
        index = 2;
    }else{
        index = -1;
    }
    Log.e("Index" , "..................." + String.valueOf(index));
    if (index == -1)
        return POSITION_NONE;
    else
        return index;
}

public String getFragmentTag(int pos){
    return "android:switcher:"+R.id.pager+":"+pos;
}

public void NotifyDataChange(){
    this.notifyDataSetChanged();
}

public int getcontainerId(){
    return container_id;
}

public ViewGroup getContainer(){
    return this.container;
}

public List<Object> getObject(){
    return this.object;
}

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

然后在您创建的每个 Fragment 中,创建一个 updateFragment 方法。在这种方法中,您可以更改片段中需要更改的内容。例如,在我的例子中,Fragment0 包含一个 GLSurfaceView,它根据 .ply 文件的路径显示一个 3d 对象,所以在我的 updateFragment 方法中,我更改了这个 ply 文件的路径。

然后创建一个 ViewPager 实例,

viewPager = (ViewPager) findViewById(R.id.pager);

和一个 Adpater 实例,

adapter = new Adapter(getSupportFragmentManager(), 3, this);

然后这样做,

viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(1);

然后在类中初始化上面的 Adapter 类并创建一个 viewPager,每次你想更新你的一个片段(在我们的例子中是 Fragment0)时,使用以下命令:

adapter.NotifyDataChange();

adapter.destroyItem(adapter.getContainer(), 0, adapter.getObject().get(0)); // destroys page 0 in the viewPager.

fragment0 = (Fragment0) getSupportFragmentManager().findFragmentByTag(adapter.getFragmentTag(0)); // Gets fragment instance used on page 0.

fragment0.updateFragment() method which include the updates on this fragment

adapter.instantiateItem(adapter.getContainer(), 0); // re-initialize page 0.

该解决方案基于 Alvaro Luis Bustamante 建议的技术。

于 2018-02-17T08:19:50.327 回答
2

我知道我迟到了,但它仍然可以帮助某人。我只是扩展了已接受的答案,并且还添加了评论。

好吧,答案本身说它效率低下

因此,为了使其仅在需要时刷新,您可以执行此操作

private boolean refresh;

public void refreshAdapter() {
    refresh = true;
    notifyDataSetChanged();
}

@Override
public int getItemPosition(@NonNull Object object) {
    if (refresh) {
        refresh = false;
        return POSITION_NONE;
    } else {
        return super.getItemPosition(object);
    }
}
于 2019-08-05T02:34:55.613 回答
1

1.首先您必须在 Pageradapter 类中设置 getItemposition 方法 2.您必须读取 View Pager 的确切位置 3.然后将该位置作为新位置的数据位置发送 4.在 setonPageChange 内写入更新按钮 onclick 侦听器听众

我修改了该程序代码以仅设置特定的位置元素

public class MyActivity extends Activity {

private ViewPager myViewPager;
private List<String> data;
public int location=0;
public Button updateButton;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    data = new ArrayList<String>();
    data.add("A");
    data.add("B");
    data.add("C");
    data.add("D");
    data.add("E");
    data.add("F");

    myViewPager = (ViewPager) findViewById(R.id.pager);
    myViewPager.setAdapter(new MyViewPagerAdapter(this, data));

      updateButton = (Button) findViewById(R.id.update);

    myViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int i, float v, int i2) {
             //Toast.makeText(MyActivity.this, i+"  Is Selected  "+data.size(), Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onPageSelected( int i) {
          // here you will get the position of selected page
            final int k = i;
             updateViewPager(k);

        }

        @Override
        public void onPageScrollStateChanged(int i) {

        }
    });
}

private void updateViewPager(final int i) {  
    updateButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            Toast.makeText(MyActivity.this, i+"  Is Selected  "+data.size(), Toast.LENGTH_SHORT).show();
            data.set(i, "Replaced "+i);         
            myViewPager.getAdapter().notifyDataSetChanged();
        }
    });

}

private class MyViewPagerAdapter extends PagerAdapter {

    private List<String> data;
    private Context ctx;

    public MyViewPagerAdapter(Context ctx, List<String> data) {
        this.ctx = ctx;
        this.data = data;
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    @Override
    public Object instantiateItem(View collection, int position) {          

        TextView view = new TextView(ctx);
        view.setText(data.get(position));
        ((ViewPager)collection).addView(view);            
        return view;
    }

    @Override
    public void destroyItem(View collection, int position, Object view) {
         ((ViewPager) collection).removeView((View) view);
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public Parcelable saveState() {
        return null;
    }

    @Override
    public void restoreState(Parcelable arg0, ClassLoader arg1) {
    }

    @Override
    public void startUpdate(View arg0) {
    }

    @Override
    public void finishUpdate(View arg0) {
    }
}
}
于 2014-01-06T09:09:53.107 回答
1

对我有用的是viewPager.getAdapter().notifyDataSetChanged();

并在适配器中放置用于更新视图的代码,getItemPosition如下所示

@Override
public int getItemPosition(Object object) {

    if (object instanceof YourViewInViewPagerClass) { 
        YourViewInViewPagerClass view = (YourViewInViewPagerClass)object;
        view.setData(data);
    }

    return super.getItemPosition(object);
}

可能不是最正确的方法,但它有效(这个return POSITION_NONE技巧对我造成了崩溃,所以不是一个选择)

于 2015-01-22T09:02:55.123 回答
1

总是返回POSITION_NONE是简单但有点低效的方式,因为这会引发所有已经实例化的页面的实例化。

我创建了一个库 ArrayPagerAdapter来动态更改 PagerAdapters 中的项目。

在内部,此库的适配器仅POSITION_NONEgetItemPosiition()必要时才返回。

您可以使用此库动态更改项目,如下所示。

@Override
protected void onCreate(Bundle savedInstanceState) {
        /** ... **/
    adapter = new MyStatePagerAdapter(getSupportFragmentManager()
                            , new String[]{"1", "2", "3"});
    ((ViewPager)findViewById(R.id.view_pager)).setAdapter(adapter);
     adapter.add("4");
     adapter.remove(0);
}

class MyPagerAdapter extends ArrayViewPagerAdapter<String> {

    public MyPagerAdapter(String[] data) {
        super(data);
    }

    @Override
    public View getView(LayoutInflater inflater, ViewGroup container, String item, int position) {
        View v = inflater.inflate(R.layout.item_page, container, false);
        ((TextView) v.findViewById(R.id.item_txt)).setText(item);
        return v;
    }
}

Thils 库还支持由 Fragments 创建的页面。

于 2016-04-04T10:57:06.933 回答
1

这是一个可怕的问题,我很高兴提出一个很好的解决方案;简单、高效、有效!

见下文,代码显示使用标志来指示何时返回 POSITION_NONE

public class ViewPagerAdapter extends PagerAdapter
{
    // Members
    private boolean mForceReinstantiateItem = false;

    // This is used to overcome terrible bug that Google isn't fixing
    // We know that getItemPosition() is called right after notifyDataSetChanged()
    // Therefore, the fix is to return POSITION_NONE right after the notifyDataSetChanged() was called - but only once
    @Override
    public int getItemPosition(Object object)
    {
        if (mForceReinstantiateItem)
        {
            mForceReinstantiateItem = false;
            return POSITION_NONE;
        }
        else
        {
            return super.getItemPosition(object);
        }
    }

    public void setData(ArrayList<DisplayContent> newContent)
    {
        mDisplayContent = newContent;
        mForceReinstantiateItem = true;
        notifyDataSetChanged();
    }

}
于 2016-07-09T20:27:29.377 回答
1

这适用于像我这样需要从服务(或其他后台线程)更新 Viewpager 并且所有建议都不起作用的人:经过一些日志检查后,我意识到 notifyDataSetChanged() 方法永远不会返回。getItemPosition(Object object) 在那里被称为全端,无需进一步处理。然后我在父 PagerAdapter 类的文档中找到(不在子类的文档中),“数据集更改必须发生在主线程上,并且必须以调用 notifyDataSetChanged() 结束”。因此,这种情况下的工作解决方案是(使用 FragmentStatePagerAdapter 和 getItemPosition(Object object) 设置为返回 POSITION_NONE):

然后调用 notifyDataSetChanged() :

runOnUiThread(new Runnable() {
         @Override
         public void run() {
             pager.getAdapter().notifyDataSetChanged();
         }
     });
于 2017-05-18T08:25:47.817 回答
1

您可以像这样在 Viewpager 上添加寻呼机转换

myPager.setPageTransformer(true, new MapPagerTransform());

在下面的代码中,当寻呼机滚动时,我在运行时更改了视图颜色

public class MapPagerTransform implements ViewPager.PageTransformer {

    public void transformPage(View view, float position) {
        LinearLayout showSelectionLL = (LinearLayout) view.findViewById(R.id.showSelectionLL);

        if (position < 0) {
            showSelectionLL.setBackgroundColor(Color.WHITE);
        } else if (position > 0) {
            showSelectionLL.setBackgroundColor(Color.WHITE);
        } else {
            showSelectionLL.setBackgroundColor(Color.RED);
        }
    }
}
于 2017-12-28T07:47:48.547 回答
1

在我的情况下,我的 Viewpager 中有一个 textView,在 mainActivity 中单击一个按钮,我想更改该 textView 的颜色并更新 pagerAdapter。在按钮上单击我将颜色保存在 SharedPreference 中并更新 pagerAdapter,它可以更新从共享偏好中获取的颜色。所以,我通过以下方式更新 viewPager 视图。

btn_purple.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int color = ContextCompat.getColor(mContext, R.color.colorPrimaryDark2);
                editor.putInt("sahittoFontColor", color);
                editor.apply();
                toNotifyDatasetChanged();
            }
        });

现在更新方法:

 private  void  toNotifyDatasetChanged (){
        if(viewPager!=null&& pagerAdapter!=null) {
            viewPager.setAdapter(null);
            viewPager.setAdapter(pagerAdapter);
           
        }

    }

我的 pagerAdapter 是:

pagerAdapter = new  Sahitto_ViewPagerAdapter (mContext, filenameParameter, 30, lineList);
                        viewPager.setAdapter(pagerAdapter);

在 instantiateItem 中是(在 PagerAdapter 中):

    SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mContext);
    int   bnfntcolor=settings.getInt("sahittoFontColor", 0);
if (bnfntcolor!=0){
    textView.setTextColor(bnfntcolor);
}

因此,当我单击按钮时,pagerAdapter 的 Textview 中的颜色会立即发生变化。

快乐编码。

于 2020-11-18T15:48:03.633 回答
1

在 ViewPager2 中,您可以再次重新初始化适配器以使用新视图刷新寻呼机列表。viewPager2.adapter = myPagerAdapter

于 2021-06-20T01:36:46.660 回答
0

我实际上使用notifyDataSetChanged()onViewPager并且CirclePageIndicator之后我调用destroyDrawingCache()ViewPager并且它有效.. 没有其他解决方案对我有用。

于 2013-07-09T08:56:28.687 回答
0

POSITION_NONE您可以按照我在这里的建议进行操作,而不是再次返回和创建所有片段:动态更新 ViewPager?

于 2013-07-25T10:43:58.430 回答
0

我想我已经做了一个简单的方法来通知数据集的变化:

首先,稍微改变一下 instantiateItem 函数的工作方式:

    @Override
    public Object instantiateItem(final ViewGroup container, final int position) {
        final View rootView = mInflater.inflate(...,container, false);
        rootView.setTag(position);
        updateView(rootView, position);
        container.addView(rootView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mViewPager.setObjectForPosition(rootView, position);
        return rootView;
    }

对于 "updateView" ,用您希望填充的所有数据填充视图 (setText,setBitmapImage,...) 。

验证 destroyView 的工作方式如下:

    @Override
    public void destroyItem(final ViewGroup container, final int position, final Object obj) {
        final View viewToRemove = (View) obj;
        mViewPager.removeView(viewToRemove);
    }

现在,假设您需要更改数据,执行此操作,然后调用 PagerAdapter 上的下一个函数:

    public void notifyDataSetChanged(final ViewPager viewPager, final NotifyLocation fromPos,
            final NotifyLocation toPos) {
        final int offscreenPageLimit = viewPager.getOffscreenPageLimit();
        final int fromPosInt = fromPos == NotifyLocation.CENTER ? mSelectedPhotoIndex
                : fromPos == NotifyLocation.MOST_LEFT ? mSelectedPhotoIndex - offscreenPageLimit
                        : mSelectedPhotoIndex + offscreenPageLimit;
        final int toPosInt = toPos == NotifyLocation.CENTER ? mSelectedPhotoIndex
                : toPos == NotifyLocation.MOST_LEFT ? mSelectedPhotoIndex - offscreenPageLimit
                        : mSelectedPhotoIndex + offscreenPageLimit;
        if (fromPosInt <= toPosInt) {
            notifyDataSetChanged();
            for (int i = fromPosInt; i <= toPosInt; ++i) {
                final View pageView = viewPager.findViewWithTag(i);
                mPagerAdapter.updateView(pageView, i);
            }
        }
    }

public enum NotifyLocation {
    MOST_LEFT, CENTER, MOST_RIGHT
}

例如,如果您希望通知 viewPager 显示的所有视图发生了变化,您可以调用:

notifyDataSetChanged(mViewPager,NotifyLocation.MOST_LEFT,NotifyLocation.MOST_RIGHT);

就是这样。

于 2014-07-07T11:52:04.663 回答
0

对于它的价值,在 KitKat+ 上似乎adapter.notifyDataSetChanged()足以让新视图出现,只要你setOffscreenPageLimit足够高。我可以通过做得到想要的行为viewPager.setOffscreenPageLimit(2)

于 2015-03-18T01:10:45.170 回答
0

我在这里留下了我自己的解决方案,这是一种解决方法,因为问题似乎是FragmentPagerAdapter不清理以前的fragments,您可以添加到ViewPager片段管理器中的 , 中。因此,我创建了一个在添加之前执行的方法FragmentPagerAdapter

(在我的情况下,我从不添加超过 3 个片段,但您可以使用例如getFragmentManager().getBackStackEntryCount()并检查所有fragments.

/**
 * this method is solving a bug in FragmentPagerAdapter which don't delete in the fragment manager any previous fragments in a ViewPager.
 *
 * @param containerId
 */
public void cleanBackStack(long containerId) {
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    for (int i = 0; i < 3; ++i) {
        String tag = "android:switcher:" + containerId + ":" + i;
        Fragment f = getFragmentManager().findFragmentByTag(tag);
        if (f != null) {
            transaction.remove(f);
        }
    }
    transaction.commit();
}

我知道这是一种解决方法,因为如果框架创建标签的方式发生变化,它将停止工作。

(目前"android:switcher:" + containerId + ":" + i

那么使用方法就是拿到容器之后:

ViewPager viewPager = (ViewPager) view.findViewById(R.id.view_pager);
cleanBackStack(viewPager.getId());
于 2016-08-18T16:04:05.200 回答
0

就我而言,每次输入 Fragment 时,onCreateView我都会重新启动值,因此请处理 null 或空值,例如:

if (var == null) {
    var = new Something();
}

if (list.isEmpty()) {
    list = new ArrayList<MyItem>();
}

if (myAdapter == null) {
    myAdapter = new CustomAdapter();
    recyclerView.setAdapter(myAdapter);
}

// etc...

onCreateView每次我们更改时片段类都可以进入,并在运行时从 UI 回到视图。

于 2016-09-10T06:27:16.790 回答
0

我正在使用带有 ViewPagerAdapter 的 Tablayout。为了在片段之间传递数据或在片段之间进行通信,请使用以下代码,该代码可以正常工作并在片段出现时刷新片段。在第二个片段的内部按钮单击写下面的代码。

b.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            String text=e1.getText().toString(); // get the text from EditText

            // move from one fragment to another fragment on button click
            TabLayout tablayout = (TabLayout) getActivity().findViewById(R.id.tab_layout); // here tab_layout is the id of TabLayout which is there in parent Activity/Fragment
            if (tablayout.getTabAt(1).isSelected()) { // here 1 is the index number of second fragment i-e current Fragment

                LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext());
                Intent i = new Intent("EDIT_TAG_REFRESH");
                i.putExtra("MyTextValue",text);
                lbm.sendBroadcast(i);

            }
            tablayout.getTabAt(0).select(); // here 0 is the index number of first fragment i-e to which fragment it has to moeve

        }
    });

下面是必须在第一个片段(在我的情况下)中编写的代码,即接收片段。

MyReceiver r;
Context context;
String newValue;
public void refresh() {
    //your code in refresh.
    Log.i("Refresh", "YES");
}
public void onPause() {
    super.onPause();

    LocalBroadcastManager.getInstance(context).unregisterReceiver(r);
}
public void onResume() {
    super.onResume();
    r = new MyReceiver();
    LocalBroadcastManager.getInstance(getActivity()).registerReceiver(r,
            new IntentFilter("EDIT_TAG_REFRESH"));
} // this code has to be written before onCreateview()


 // below code can be written any where in the fragment
 private class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    PostRequestFragment.this.refresh();
        String action = intent.getAction();
        newValue=intent.getStringExtra("MyTextValue");
        t1.setText(newValue); // upon Referesh set the text
    }
}
于 2016-09-28T07:38:53.530 回答
0

对我有用的是覆盖该finishUpdate方法,该方法在转换结束时调用并在notifyDataSetChanged()那里执行:

public class MyPagerAdapter extends FragmentPagerAdapter {
    ...
    @Override
    public void finishUpdate(ViewGroup container) {
        super.finishUpdate(container);
        this.notifyDataSetChanged();
    }
    ...
}
于 2017-05-09T11:48:29.520 回答
0

覆盖getItemPosition()的正确方法:

@Override
public int getItemPosition(@NonNull Object object) {
    if (!(object instanceof MyPageView)) {
        // Should never happen
        return super.getItemPosition(object);
    }
    MyDataObject dataObject = ((MyPageView) object).getData();
    if (!(dataObject instanceof MyDataObject)) {
        // Should never happen
        return super.getItemPosition(object);
    }
    if (lstItems.contains(dataObject)) {
        return POSITION_UNCHANGED;
    }
    return POSITION_NONE;
}

简而言之,您需要将用于绘制视图的数据附加/保存到视图中。从那里,当 getItemPosition() 被调用时,ViewPager 可以确定当前显示的视图是否仍然存在于适配器上,并采取相应的行动。

于 2018-11-14T16:25:57.310 回答
0

你只需要这个简单的代码:

代码:

private void updateAdapter() {
    if (adapterViewPager != null) {
        int from = vpMyViewPager.getCurrentItem() - vpMyViewPager.getOffscreenPageLimit();
        int to = vpMyViewPager.getCurrentItem() + vpMyViewPager.getOffscreenPageLimit();
        vpMyViewPager.removeAllViews();
        for (int i = from; i <= to; i++) {
            if (i < 0) {
                continue;
            }
            adapterViewPager.instantiateItem(vpMyViewPager, i);
        }
    }
}

解释:

如果你没有改变offscreenPageLimitViewPager它总是有 3 到 4 个孩子,这取决于你要去的方向。为了在其子项中显示正确的内容,它使用适配器来获取正确的内容。现在,当您调用removeAllViews()ViewPager,实际上只有 3 到 4View秒从Window' 的层次结构中删除,并且通过调用instantiateItem(ViewGroup viewPager, int index),您只重新创建 3 到 4View秒。然后一切恢复正常,您滑动和滚动,ViewPager使用其适配器显示内容。在所有情况下,所有设备上的子节点数量都不相同,例如,如果将 设置offscreenPageLimit为 5,它可能会有大约 11 到 12 个子节点,但仅此而已,并不多。它很快。

于 2018-11-24T02:36:39.333 回答
0

根据我的经验,最好的解决方案是:https ://stackoverflow.com/a/44177688/3118950 ,它覆盖long getItemId()并返回唯一 ID 而不是默认位置。除了导入该答案之外,请注意旧片段将保留在片段管理器中,以防总量小于页面限制,并且onDetach()/onDestory()在替换片段时不会被调用。

于 2019-02-15T11:17:15.357 回答
0

所有这些答案都不适合我。

唯一对我有用的是我必须再次将适配器设置为 viewpager,然后它将刷新内容。

我的 PagerAdaper 中的 removeView(int pos)

public void removeView(int index) {
       imageFileNames.remove(index);
       notifyDataSetChanged();
}

无论我在哪里删除文件,我都必须这样做

imagePagerAdapter.removeView(currentPosition);
viewPager.setAdapter(imagePagerAdapter);

编辑:

下面这个方法是有效的,你可以应用下面的一个。

public void updateView(int pos){
      viewPager.setAdapter(null);
      imagePagerAdapter =new ImagePagerAdapter(YOUR_CONTEXT,YOUR_CONTENT);
      viewPager.setAdapter(imagePagerAdapter);
      viewPager.setCurrentItem(pos);
}

将 YOUR_CONTEXT 替换为您的上下文,将您的内容替换为您的内容名称,即更新列表或其他内容。

于 2020-01-24T13:55:57.657 回答
-12

mTabsAdapter.onTabChanged(mTabHost.getCurrentTabTag());在更新视图之前触发。这将起作用。

于 2011-12-09T03:17:18.037 回答