Android ViewPager PagerAdapter不更新视图
我正在使用兼容性库中的ViewPager。我成功地让它显示了几个我可以翻页浏览的视图 但是,我很难弄清楚如何用一组新的视图更新ViewPager 我尝试过各种方法,比如调用Android ViewPager PagerAdapter不更新视图,android,android-viewpager,Android,Android Viewpager,我正在使用兼容性库中的ViewPager。我成功地让它显示了几个我可以翻页浏览的视图 但是,我很难弄清楚如何用一组新的视图更新ViewPager 我尝试过各种方法,比如调用mAdapter.notifyDataSetChanged(),mViewPager.invalidate(),甚至每次我想使用新的数据列表时都要创建一个全新的适配器 没有任何帮助,文本视图与原始数据保持不变 更新: 我做了一个小测试项目,几乎可以更新视图。我将把班级贴在下面 但是,第二个视图似乎没有更新,“B”仍然存在,按下
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) {
}
}
}
public class ViewPagerBugActivity扩展活动{
私人查看页面myViewPager;
私人名单数据;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
数据=新的ArrayList();
数据。添加(“A”);
数据。添加(“B”);
数据。添加(“C”);
myViewPager=(ViewPager)findViewById(R.id.my_view_pager);
setAdapter(新的MyViewPagerAdapter(这个,数据));
按钮更新按钮=(按钮)findViewById(R.id.update_按钮);
setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
UpdateViewPage();
}
});
}
私有void updateviewpage(){
data.clear();
数据。添加(“X”);
数据。添加(“Y”);
数据。添加(“Z”);
myViewPager.getAdapter().notifyDataSetChanged();
}
私有类MyViewPagerAdapter扩展了PagerAdapter{
私人名单数据;
私有上下文ctx;
公共MyViewPagerAdapter(上下文ctx,列表数据){
this.ctx=ctx;
这个数据=数据;
}
@凌驾
public int getCount(){
返回data.size();
}
@凌驾
公共对象实例化项(视图集合,int位置){
TextView=新的TextView(ctx);
view.setText(data.get(position));
((ViewPager)集合)。添加视图(view);
返回视图;
}
@凌驾
公共项(视图集合、int位置、对象视图){
((ViewPager)集合)。移除视图((视图)视图);
}
@凌驾
公共布尔值isViewFromObject(视图,对象){
返回视图==对象;
}
@凌驾
公共包裹存储状态(){
返回null;
}
@凌驾
公共地产(地块arg0,类加载器arg1){
}
@凌驾
公共作废启动日期(视图arg0){
}
@凌驾
public void finishUpdate(视图arg0){
}
}
}
实现这一点有几种方法
第一种选择比较简单,但效率稍低
在PagerAdapter
中覆盖getItemPosition
,如下所示:
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public void destroyItem(final ViewGroup container, final int position, final Object obj) {
final View viewToRemove = (View) obj;
mViewPager.removeView(viewToRemove);
}
这样,当您调用notifyDataSetChanged()时,视图分页器将删除所有视图并重新加载它们。因此,获得了重新加载效果
第二个选项是在实例化新视图时,在实例化Item()
中使用setTag()
方法。然后,您可以使用findViewWithTag()
查找要更新的视图,而不是使用notifyDataSetChanged()
第二种方法是非常灵活和高性能的。感谢alvarolb的原始研究。我只是发布这个答案,以防其他人发现它有用。为了做完全相同的事情,我只需从兼容性库中获取ViewPager和PagerAdapter的源代码,并在我的代码中进行编译(您需要自己整理所有错误并导入,但肯定可以做到)
然后,在CustomViewPager中,创建一个名为UpdateView(int-position)的方法。视图本身可以从ViewPager类中定义的ArrayList mItems中获取(您需要在实例化项中为视图设置一个Id,并将该Id与updateView()方法中的位置进行比较)。然后您可以根据需要更新视图。我遇到了一个类似的问题,我有四个页面,其中一个页面更新了其他三个页面的视图。我能够在与当前页面相邻的页面上更新小部件(seekbar、textview等)。调用
mTabsAdapter.getItem(position)
时,最后两个页面将包含未初始化的小部件
为了解决我的问题,我在调用getItem(position)
之前使用了setSelectedPage(index)
。这将实例化页面,使我能够更改每个页面上的值和小部件
在所有更新之后,我将使用setSelectedPage(position)
然后是notifydatasetchange()
您可以在主更新页面的ListView中看到轻微的闪烁,但没有明显的变化。我还没有完全测试过它,但它确实解决了我眼前的问题 我认为
PagerAdapter
中没有任何缺陷。问题是理解它是如何工作的有点复杂。从这里解释的解决方案来看,有一个误解,因此在我看来,实例化视图的使用很差
最近几天,我一直在使用PagerAdapter
和ViewPager
,我发现:
public class myPagerAdapter extends FragmentPagerAdapter {
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;
}
}
private FragmentManager mFragmentManager;
private ArrayList<PagerItem> mPagerItems;
public MyPagerAdapter(FragmentManager fragmentManager, ArrayList<PagerItem> pagerItems) {
super(fragmentManager);
mFragmentManager = fragmentManager;
mPagerItems = pagerItems;
}
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;
}
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();
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.
PagerAdapter
上的notifyDataSetChanged()
方法将仅通知ViewPager
底层页面已更改。例如,如果您已动态创建/删除页面(从y中添加或删除项目
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);
public class myPagerAdapter extends FragmentPagerAdapter {
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;
}
}
private FragmentManager mFragmentManager;
private ArrayList<PagerItem> mPagerItems;
public MyPagerAdapter(FragmentManager fragmentManager, ArrayList<PagerItem> pagerItems) {
super(fragmentManager);
mFragmentManager = fragmentManager;
mPagerItems = pagerItems;
}
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;
}
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();
@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;
}
@Override
public void destroyItem(final ViewGroup container, final int position, final Object obj) {
final View viewToRemove = (View) obj;
mViewPager.removeView(viewToRemove);
}
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
}
notifyDataSetChanged(mViewPager,NotifyLocation.MOST_LEFT,NotifyLocation.MOST_RIGHT);
@Override
public int getItemPosition(Object object) {
if (object instanceof YourViewInViewPagerClass) {
YourViewInViewPagerClass view = (YourViewInViewPagerClass)object;
view.setData(data);
}
return super.getItemPosition(object);
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
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();
}}
@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;
}
}
@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();
}
}
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);
}
}
runOnUiThread(new Runnable() {
@Override
public void run() {
pager.getAdapter().notifyDataSetChanged();
}
});
@Override
public long getItemId(int position) {
return mPages.get(position).getId();
}
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);
}
}
}
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;
}}
viewPager = (ViewPager) findViewById(R.id.pager);
adapter = new Adapter(getSupportFragmentManager(), 3, this);
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(1);
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.
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);
}
}
dependencies {
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'
}
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
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);
}
}
}
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();
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 = new Sahitto_ViewPagerAdapter (mContext, filenameParameter, 30, lineList);
viewPager.setAdapter(pagerAdapter);
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mContext);
int bnfntcolor=settings.getInt("sahittoFontColor", 0);
if (bnfntcolor!=0){
textView.setTextColor(bnfntcolor);
}