dynamic添加和删除视图到viewpager

(我想出了一个解决scheme – 请在下面的答案部分看到我的post。)

在我的应用程序中,用户将从一个单一的数据视图开始。 我想添加一个ViewPager并允许用户根据需要添加更多的视图。 我如何做到这一点? (我不'想要使用FragmentPagerAdapter。)

我读过无数的post和概述,但仍然缺less一些东西。 这是我想我明白的:

MainActivity创build一个ViewPager和PagerAdapter:

ViewPager pager = null; MainPagerAdapter adapter = null; public void onCreate (Bundle savedInstanceState) { super.onCreate (savedInstanceState); pager = new ViewPager (this); setContentView (pager); adapter = new MainPagerAdapter(); pager.setAdapter (adapter); View v0 = code_to_create_initial_view(); adapter.add (v0, 0); } 

使用PagerAdapter提供视图集。 为此,我似乎需要添加和删除视图的方法,像这样的东西; 显然更多的是需要告诉ViewPager的东西已经改变,以及如何显示更改:

 class MainPagerAdapter extends PagerAdapter { // This holds all the currently displayable views, in order from left to right. private ArrayList<View> views = new ArrayList<View>(); public void addView (View v, int position) { views.add (position, v); } public void removeView (int position) { views.remove (position); } } 

另外,我还需要实施以下的方法。 我在这里迷路 – 什么叫他们,他们应该做什么(好吧,getCount是显而易见的)?

  public object instantiateItem (ViewGroup pager, int position); public void destroyItem (ViewGroup, int, Object); public int getCount (); public boolean isViewFromObject (View, Object); 
  • 什么是ViewGroup的参数 – 是不是包含组的ViewPager本身?
  • 什么是ViewFromObject做 – 一个对象如何与第一个地方与视图关联?
  • 当我添加或删除视图时,是否应该调用startUpdate并finishUdate?

谢谢。

在确定ViewPager调用哪些ViewPager方法以及哪些方法用于其他目的之后,我想出了一个解决scheme。 我在这里介绍它,因为我看到很多人都在为此而苦苦挣扎,我没有看到任何其他相关的答案。

首先,这是我的适配器; 希望在代码中的评论是足够的:

 public class MainPagerAdapter extends PagerAdapter { // This holds all the currently displayable views, in order from left to right. private ArrayList<View> views = new ArrayList<View>(); //----------------------------------------------------------------------------- // Used by ViewPager. "Object" represents the page; tell the ViewPager where the // page should be displayed, from left-to-right. If the page no longer exists, // return POSITION_NONE. @Override public int getItemPosition (Object object) { int index = views.indexOf (object); if (index == -1) return POSITION_NONE; else return index; } //----------------------------------------------------------------------------- // Used by ViewPager. Called when ViewPager needs a page to display; it is our job // to add the page to the container, which is normally the ViewPager itself. Since // all our pages are persistent, we simply retrieve it from our "views" ArrayList. @Override public Object instantiateItem (ViewGroup container, int position) { View v = views.get (position); container.addView (v); return v; } //----------------------------------------------------------------------------- // Used by ViewPager. Called when ViewPager no longer needs a page to display; it // is our job to remove the page from the container, which is normally the // ViewPager itself. Since all our pages are persistent, we do nothing to the // contents of our "views" ArrayList. @Override public void destroyItem (ViewGroup container, int position, Object object) { container.removeView (views.get (position)); } //----------------------------------------------------------------------------- // Used by ViewPager; can be used by app as well. // Returns the total number of pages that the ViewPage can display. This must // never be 0. @Override public int getCount () { return views.size(); } //----------------------------------------------------------------------------- // Used by ViewPager. @Override public boolean isViewFromObject (View view, Object object) { return view == object; } //----------------------------------------------------------------------------- // Add "view" to right end of "views". // Returns the position of the new view. // The app should call this to add pages; not used by ViewPager. public int addView (View v) { return addView (v, views.size()); } //----------------------------------------------------------------------------- // Add "view" at "position" to "views". // Returns position of new view. // The app should call this to add pages; not used by ViewPager. public int addView (View v, int position) { views.add (position, v); return position; } //----------------------------------------------------------------------------- // Removes "view" from "views". // Retuns position of removed view. // The app should call this to remove pages; not used by ViewPager. public int removeView (ViewPager pager, View v) { return removeView (pager, views.indexOf (v)); } //----------------------------------------------------------------------------- // Removes the "view" at "position" from "views". // Retuns position of removed view. // The app should call this to remove pages; not used by ViewPager. public int removeView (ViewPager pager, int position) { // ViewPager doesn't have a delete method; the closest is to set the adapter // again. When doing so, it deletes all its views. Then we can delete the view // from from the adapter and finally set the adapter to the pager again. Note // that we set the adapter to null before removing the view from "views" - that's // because while ViewPager deletes all its views, it will call destroyItem which // will in turn cause a null pointer ref. pager.setAdapter (null); views.remove (position); pager.setAdapter (this); return position; } //----------------------------------------------------------------------------- // Returns the "view" at "position". // The app should call this to retrieve a view; not used by ViewPager. public View getView (int position) { return views.get (position); } // Other relevant methods: // finishUpdate - called by the ViewPager - we don't care about what pages the // pager is displaying so we don't use this method. } 

这里有一些代码片段显示了如何使用适配器。

 class MainActivity extends Activity { private ViewPager pager = null; private MainPagerAdapter pagerAdapter = null; //----------------------------------------------------------------------------- @Override public void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView (R.layout.main_activity); ... do other initialization, such as create an ActionBar ... pagerAdapter = new MainPagerAdapter(); pager = (ViewPager) findViewById (R.id.view_pager); pager.setAdapter (pagerAdapter); // Create an initial view to display; must be a subclass of FrameLayout. LayoutInflater inflater = context.getLayoutInflater(); FrameLayout v0 = (FrameLayout) inflater.inflate (R.layout.one_of_my_page_layouts, null); pagerAdapter.addView (v0, 0); pagerAdapter.notifyDataSetChanged(); } //----------------------------------------------------------------------------- // Here's what the app should do to add a view to the ViewPager. public void addView (View newPage) { int pageIndex = pagerAdapter.addView (newPage); // You might want to make "newPage" the currently displayed page: pager.setCurrentItem (pageIndex, true); } //----------------------------------------------------------------------------- // Here's what the app should do to remove a view from the ViewPager. public void removeView (View defunctPage) { int pageIndex = pagerAdapter.removeView (pager, defunctPage); // You might want to choose what page to display, if the current page was "defunctPage". if (pageIndex == pagerAdapter.getCount()) pageIndex--; pager.setCurrentItem (pageIndex); } //----------------------------------------------------------------------------- // Here's what the app should do to get the currently displayed page. public View getCurrentPage () { return pagerAdapter.getView (pager.getCurrentItem()); } //----------------------------------------------------------------------------- // Here's what the app should do to set the currently displayed page. "pageToShow" must // currently be in the adapter, or this will crash. public void setCurrentPage (View pageToShow) { pager.setCurrentItem (pagerAdapter.getItemPosition (pageToShow), true); } } 

最后,你可以使用下面的activity_main.xml布局:

 <?xml version="1.0" encoding="utf-8"?> <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" > </android.support.v4.view.ViewPager> 

我正在寻找简单的解决scheme来dynamic地从viewpager(无片段)中删除视图。 所以,如果你有一些信息,你的网页属于,你可以把它设置为标签查看。 就像那样(适配器代码):

 @Override public Object instantiateItem(ViewGroup collection, int position) { ImageView iv = new ImageView(mContext); MediaMessage msg = mMessages.get(position); ... iv.setTag(media); return iv; } @Override public int getItemPosition (Object object) { View o = (View) object; int index = mMessages.indexOf(o.getTag()); if (index == -1) return POSITION_NONE; else return index; } 

您只需要从mMessages中删除您的信息,然后为您的适配器调用notifyDataSetChanged() 。 坏消息是这里没有animation。

围绕这个话题进行了很多讨论

  • ViewPager PagerAdapter不更新视图
  • dynamic更新ViewPager?
  • 从FragmentStatePagerAdapter中删除片段

虽然我们经常看到它,但是使用POSITION_NONE似乎并不是要走的路,因为这是非常低效的记忆方式。

在这个问题上,我们应该考虑使用阿尔瓦罗的方法 :

…是在instantiateItem()化新视图时在instantiateItem() setTag()方法。 然后,可以使用findViewWithTag()来查找要更新的视图,而不是使用notifyDataSetChanged()

这是基于这个想法的代码的答案

我做了一个类似的程序。 希望这可以帮助你。在第一个活动中,可以select四个网格数据。 在下一个活动中,有一个包含两个强制页面的查看寻呼机。另外还有4个页面,这些页面对应于所选的网格数据将是可见的。

以下是MainActivity的主要活动

  package com.example.jeffy.viewpagerapp; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.os.Parcel; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.widget.AdapterView; import android.widget.Button; import android.widget.GridView; import java.lang.reflect.Array; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { SharedPreferences pref; SharedPreferences.Editor editor; GridView gridView; Button button; private static final String DATABASE_NAME = "dbForTest.db"; private static final int DATABASE_VERSION = 1; private static final String TABLE_NAME = "diary"; private static final String TITLE = "id"; private static final String BODY = "content"; DBHelper dbHelper = new DBHelper(this); ArrayList<String> frags = new ArrayList<String>(); ArrayList<FragmentArray> fragmentArray = new ArrayList<FragmentArray>(); String[] selectedData; Boolean port1=false,port2=false,port3=false,port4=false; int Iport1=1,Iport2=1,Iport3=1,Iport4=1,location; // This Data show in grid ( Used by adapter ) CustomGridAdapter customGridAdapter = new CustomGridAdapter(MainActivity.this,GRID_DATA); static final String[ ] GRID_DATA = new String[] { "1" , "2", "3" , "4" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); frags.add("TabFragment3"); frags.add("TabFragment4"); frags.add("TabFragment5"); frags.add("TabFragment6"); dbHelper = new DBHelper(this); dbHelper.insertContact(1,0); dbHelper.insertContact(2,0); dbHelper.insertContact(3,0); dbHelper.insertContact(4,0); final Bundle selected = new Bundle(); button = (Button) findViewById(R.id.button); pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE); editor = pref.edit(); gridView = (GridView) findViewById(R.id.gridView1); gridView.setAdapter(customGridAdapter); gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //view.findViewById(R.id.grid_item_image).setVisibility(View.VISIBLE); location = position + 1; if (position == 0) { Iport1++; Iport1 = Iport1 % 2; if (Iport1 % 2 == 1) { //dbHelper.updateContact(1,1); view.findViewById(R.id.grid_item_image).setVisibility(View.VISIBLE); dbHelper.updateContact(1,1); } else { //dbHelper.updateContact(1,0); view.findViewById(R.id.grid_item_image).setVisibility(View.INVISIBLE); dbHelper.updateContact(1, 0); } } if (position == 1) { Iport2++; Iport1 = Iport1 % 2; if (Iport2 % 2 == 1) { //dbHelper.updateContact(2,1); view.findViewById(R.id.grid_item_image).setVisibility(View.VISIBLE); dbHelper.updateContact(2, 1); } else { //dbHelper.updateContact(2,0); view.findViewById(R.id.grid_item_image).setVisibility(View.INVISIBLE); dbHelper.updateContact(2,0); } } if (position == 2) { Iport3++; Iport3 = Iport3 % 2; if (Iport3 % 2 == 1) { //dbHelper.updateContact(3,1); view.findViewById(R.id.grid_item_image).setVisibility(View.VISIBLE); dbHelper.updateContact(3, 1); } else { //dbHelper.updateContact(3,0); view.findViewById(R.id.grid_item_image).setVisibility(View.INVISIBLE); dbHelper.updateContact(3, 0); } } if (position == 3) { Iport4++; Iport4 = Iport4 % 2; if (Iport4 % 2 == 1) { //dbHelper.updateContact(4,1); view.findViewById(R.id.grid_item_image).setVisibility(View.VISIBLE); dbHelper.updateContact(4, 1); } else { //dbHelper.updateContact(4,0); view.findViewById(R.id.grid_item_image).setVisibility(View.INVISIBLE); dbHelper.updateContact(4,0); } } } }); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { editor.putInt("port1", Iport1); editor.putInt("port2", Iport2); editor.putInt("port3", Iport3); editor.putInt("port4", Iport4); Intent i = new Intent(MainActivity.this,Main2Activity.class); if(Iport1==1) i.putExtra("3","TabFragment3"); else i.putExtra("3", ""); if(Iport2==1) i.putExtra("4","TabFragment4"); else i.putExtra("4",""); if(Iport3==1) i.putExtra("5", "TabFragment5"); else i.putExtra("5",""); if(Iport4==1) i.putExtra("6", "TabFragment6"); else i.putExtra("6",""); dbHelper.updateContact(0, Iport1); dbHelper.updateContact(1, Iport2); dbHelper.updateContact(2, Iport3); dbHelper.updateContact(3, Iport4); startActivity(i); } }); } } 

这里TabFragment1,TabFragment2等是片段要显示在viewpager.And我没有显示布局,因为他们超出了这个项目的范围。

MainActivity将意图为Main2Activity Main2Activity

  package com.example.jeffy.viewpagerapp; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.support.design.widget.CollapsingToolbarLayout; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.design.widget.TabLayout; import android.support.v4.view.ViewPager; import android.support.v4.widget.NestedScrollView; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.FrameLayout; import java.util.ArrayList; public class Main2Activity extends AppCompatActivity { private ViewPager pager = null; private PagerAdapter pagerAdapter = null; DBHelper dbHelper; Cursor rs; int port1,port2,port3,port4; //----------------------------------------------------------------------------- @Override public void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); Toolbar toolbar = (Toolbar) findViewById(R.id.MyToolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapse_toolbar); NestedScrollView scrollView = (NestedScrollView) findViewById (R.id.nested); scrollView.setFillViewport (true); ArrayList<String > selectedPort = new ArrayList<String>(); Intent intent = getIntent(); String Tab3 = intent.getStringExtra("3"); String Tab4 = intent.getStringExtra("4"); String Tab5 = intent.getStringExtra("5"); String Tab6 = intent.getStringExtra("6"); TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout); tabLayout.addTab(tabLayout.newTab().setText("View")); tabLayout.addTab(tabLayout.newTab().setText("All")); selectedPort.add("TabFragment1"); selectedPort.add("TabFragment2"); if(Tab3!=null && !TextUtils.isEmpty(Tab3)) selectedPort.add(Tab3); if(Tab4!=null && !TextUtils.isEmpty(Tab4)) selectedPort.add(Tab4); if(Tab5!=null && !TextUtils.isEmpty(Tab5)) selectedPort.add(Tab5); if(Tab6!=null && !TextUtils.isEmpty(Tab6)) selectedPort.add(Tab6); dbHelper = new DBHelper(this); // rs=dbHelper.getData(1); // port1 = rs.getInt(rs.getColumnIndex("id")); // // rs=dbHelper.getData(2); // port2 = rs.getInt(rs.getColumnIndex("id")); // // rs=dbHelper.getData(3); // port3 = rs.getInt(rs.getColumnIndex("id")); // // rs=dbHelper.getData(4); // port4 = rs.getInt(rs.getColumnIndex("id")); Log.i(">>>>>>>>>>>>>>", "port 1" + port1 + "port 2" + port2 + "port 3" + port3 + "port 4" + port4); if(Tab3!=null && !TextUtils.isEmpty(Tab3)) tabLayout.addTab(tabLayout.newTab().setText("Tab 0")); if(Tab3!=null && !TextUtils.isEmpty(Tab4)) tabLayout.addTab(tabLayout.newTab().setText("Tab 1")); if(Tab3!=null && !TextUtils.isEmpty(Tab5)) tabLayout.addTab(tabLayout.newTab().setText("Tab 2")); if(Tab3!=null && !TextUtils.isEmpty(Tab6)) tabLayout.addTab(tabLayout.newTab().setText("Tab 3")); tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); final ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager); final PagerAdapter adapter = new PagerAdapter (getSupportFragmentManager(), tabLayout.getTabCount(), selectedPort); viewPager.setAdapter(adapter); viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { viewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(TabLayout.Tab tab) { } @Override public void onTabReselected(TabLayout.Tab tab) { } }); // setContentView(R.layout.activity_main2); // Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); // setSupportActionBar(toolbar); // TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout); // tabLayout.addTab(tabLayout.newTab().setText("View")); // tabLayout.addTab(tabLayout.newTab().setText("All")); // tabLayout.addTab(tabLayout.newTab().setText("Tab 0")); // tabLayout.addTab(tabLayout.newTab().setText("Tab 1")); // tabLayout.addTab(tabLayout.newTab().setText("Tab 2")); // tabLayout.addTab(tabLayout.newTab().setText("Tab 3")); // tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); } } 

ViewPagerAdapter Viewpageradapter.class

 package com.example.jeffy.viewpagerapp; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.view.ViewPager; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; import java.util.List; /** * Created by Jeffy on 25-01-2016. */ public class PagerAdapter extends FragmentStatePagerAdapter { int mNumOfTabs; List<String> values; public PagerAdapter(FragmentManager fm, int NumOfTabs, List<String> Port) { super(fm); this.mNumOfTabs = NumOfTabs; this.values= Port; } @Override public Fragment getItem(int position) { String fragmentName = values.get(position); Class<?> clazz = null; Object fragment = null; try { clazz = Class.forName("com.example.jeffy.viewpagerapp."+fragmentName); } catch (ClassNotFoundException e) { e.printStackTrace(); } try { fragment = clazz.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return (Fragment) fragment; } @Override public int getCount() { return values.size(); } } 

main2activity acticity_main2.xml的布局

  <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <android.support.design.widget.AppBarLayout android:id="@+id/MyAppbar" android:layout_width="match_parent" android:layout_height="256dp" android:fitsSystemWindows="true"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapse_toolbar" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll|exitUntilCollapsed" android:background="@color/material_deep_teal_500" android:fitsSystemWindows="true"> <ImageView android:id="@+id/bgheader" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:fitsSystemWindows="true" android:background="@drawable/screen" app:layout_collapseMode="pin" /> <android.support.v7.widget.Toolbar android:id="@+id/MyToolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="parallax" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:id="@+id/nested" android:layout_height="match_parent" android:layout_gravity="fill_vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.design.widget.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/MyToolbar" android:background="?attr/colorPrimary" android:elevation="6dp" android:minHeight="?attr/actionBarSize" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/> <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" > </android.support.v4.view.ViewPager> </LinearLayout> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.CoordinatorLayout> Mainactivity layout activity_main.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="com.example.jeffy.viewpagerapp.MainActivity" tools:showIn="@layout/activity_main"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gridView1" android:numColumns="2" android:gravity="center" android:columnWidth="100dp" android:stretchMode="columnWidth" android:layout_width="fill_parent" android:layout_height="fill_parent" > </GridView> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="SAVE" android:id="@+id/button" /> </LinearLayout> </RelativeLayout> 

希望这将有助于某人…请点击button,如果这有助于你

我创build了一个自定义的PagerAdapters库来dynamic改变PagerAdapters中的项目。

您可以像使用此库一样dynamic更改项目。

 @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创build的页面。

这是这个问题的另一种解决scheme。 我的适配器:

  private class PagerAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener, TabListener { private List<Fragment> mFragments = new ArrayList<Fragment>(); private ViewPager mPager; private ActionBar mActionBar; private Fragment mPrimaryItem; public PagerAdapter(FragmentManager fm, ViewPager vp, ActionBar ab) { super(fm); mPager = vp; mPager.setAdapter(this); mPager.setOnPageChangeListener(this); mActionBar = ab; } public void addTab(PartListFragment frag) { mFragments.add(frag); mActionBar.addTab(mActionBar.newTab().setTabListener(this). setText(frag.getPartCategory())); } @Override public Fragment getItem(int position) { return mFragments.get(position); } @Override public int getCount() { return mFragments.size(); } /** (non-Javadoc) * @see android.support.v4.app.FragmentStatePagerAdapter#setPrimaryItem(android.view.ViewGroup, int, java.lang.Object) */ @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { super.setPrimaryItem(container, position, object); mPrimaryItem = (Fragment) object; } /** (non-Javadoc) * @see android.support.v4.view.PagerAdapter#getItemPosition(java.lang.Object) */ @Override public int getItemPosition(Object object) { if (object == mPrimaryItem) { return POSITION_UNCHANGED; } return POSITION_NONE; } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { mPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { } @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { } @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int position) { mActionBar.setSelectedNavigationItem(position); } /** * This method removes the pages from ViewPager */ public void removePages() { mActionBar.removeAllTabs(); //call to ViewPage to remove the pages vp.removeAllViews(); mFragments.clear(); //make this to update the pager vp.setAdapter(null); vp.setAdapter(pagerAdapter); } } 

代码dynamic删除和添加

 //remove the pages. basically call to method removeAllViews from `ViewPager` pagerAdapter.removePages(); pagerAdapter.addPage(pass your fragment); 

在Peri Hartman的build议之后,在我设置了null之后,ViewPager适配器开始工作,并在删除视图之后再次将适配器放置。 在此之前,页面0不显示其列表内容。

谢谢。

要删除你可以直接使用这个:

 getSupportFragmentManager().beginTransaction().remove(fragment). commitAllowingStateLoss(); 

fragment是您想要删除的片段。

我发现这个问题的一个很好的解决scheme,这个解决scheme可以使其工作,而不需要重新创build碎片。
我的重点是:

  1. 每次删除或添加Tab(Fragment)时都要设置ViewPager。
  2. 重写getItemId方法,返回一个特定的ID而不是位置。

源代码

 package com.zq.testviewpager; import android.support.annotation.Nullable; import android.support.design.widget.TabLayout; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.ArrayList; import java.util.Arrays; /** * Created by z8888q@gmail.com on 2017/5/31. * Implement dynamic delete or add tab(TAB_C in this test code). */ public class MainActivity extends AppCompatActivity { private static final int TAB_A = 1001; private static final int TAB_B = 1002; private static final int TAB_C = 1003; private static final int TAB_D = 1004; private static final int TAB_E = 1005; private Tab[] tabsArray = new Tab[]{new Tab(TAB_A, "A"),new Tab(TAB_B, "B"),new Tab(TAB_C, "C"),new Tab(TAB_D, "D"),new Tab(TAB_E, "E")}; private ArrayList<Tab> mTabs = new ArrayList<>(Arrays.asList(tabsArray)); private Tab[] tabsArray2 = new Tab[]{new Tab(TAB_A, "A"),new Tab(TAB_B, "B"),new Tab(TAB_D, "D"),new Tab(TAB_E, "E")}; private ArrayList<Tab> mTabs2 = new ArrayList<>(Arrays.asList(tabsArray2)); /** * The {@link android.support.v4.view.PagerAdapter} that will provide * fragments for each of the sections. We use a * {@link FragmentPagerAdapter} derivative, which will keep every * loaded fragment in memory. If this becomes too memory intensive, it * may be best to switch to a * {@link android.support.v4.app.FragmentStatePagerAdapter}. */ private SectionsPagerAdapter mSectionsPagerAdapter; /** * The {@link ViewPager} that will host the section contents. */ private ViewPager mViewPager; private TabLayout tabLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); // Create the adapter that will return a fragment for each of the three // primary sections of the activity. mSectionsPagerAdapter = new SectionsPagerAdapter(mTabs, getSupportFragmentManager()); // Set up the ViewPager with the sections adapter. mViewPager = (ViewPager) findViewById(R.id.container); mViewPager.setAdapter(mSectionsPagerAdapter); tabLayout = (TabLayout) findViewById(R.id.tabs); tabLayout.setupWithViewPager(mViewPager); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; }else if (id == R.id.action_delete) { int currentItemPosition = mViewPager.getCurrentItem(); Tab currentTab = mTabs.get(currentItemPosition); if(currentTab.id == TAB_C){ currentTab = mTabs.get(currentItemPosition == 0 ? currentItemPosition +1 : currentItemPosition - 1); } mSectionsPagerAdapter = new SectionsPagerAdapter(mTabs2, getSupportFragmentManager()); mViewPager.setAdapter(mSectionsPagerAdapter); tabLayout.setupWithViewPager(mViewPager); mViewPager.setCurrentItem(mTabs2.indexOf(currentTab), false); return true; }else if (id == R.id.action_add) { int currentItemPosition = mViewPager.getCurrentItem(); Tab currentTab = mTabs2.get(currentItemPosition); mSectionsPagerAdapter = new SectionsPagerAdapter(mTabs, getSupportFragmentManager()); mViewPager.setAdapter(mSectionsPagerAdapter); tabLayout.setupWithViewPager(mViewPager); mViewPager.setCurrentItem(mTabs.indexOf(currentTab), false); return true; }else return super.onOptionsItemSelected(item); } /** * A placeholder fragment containing a simple view. */ public static class PlaceholderFragment extends Fragment { /** * The fragment argument representing the section number for this * fragment. */ private static final String ARG_SECTION_NUMBER = "section_number"; public PlaceholderFragment() { } /** * Returns a new instance of this fragment for the given section * number. */ public static PlaceholderFragment newInstance(int sectionNumber) { PlaceholderFragment fragment = new PlaceholderFragment(); Bundle args = new Bundle(); args.putInt(ARG_SECTION_NUMBER, sectionNumber); fragment.setArguments(args); return fragment; } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e("TestViewPager", "onCreate"+getArguments().getInt(ARG_SECTION_NUMBER)); } @Override public void onDestroy() { super.onDestroy(); Log.e("TestViewPager", "onDestroy"+getArguments().getInt(ARG_SECTION_NUMBER)); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); TextView textView = (TextView) rootView.findViewById(R.id.section_label); textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER))); return rootView; } } /** * A {@link FragmentPagerAdapter} that returns a fragment corresponding to * one of the sections/tabs/pages. */ public class SectionsPagerAdapter extends FragmentPagerAdapter { ArrayList<Tab> tabs; public SectionsPagerAdapter(ArrayList<Tab> tabs, FragmentManager fm) { super(fm); this.tabs = tabs; } @Override public Fragment getItem(int position) { // getItem is called to instantiate the fragment for the given page. // Return a PlaceholderFragment (defined as a static inner class below). return PlaceholderFragment.newInstance(tabs.get(position).id); } @Override public int getCount() { return tabs.size(); } @Override public long getItemId(int position) { return tabs.get(position).id; } @Override public CharSequence getPageTitle(int position) { return tabs.get(position).title; } } private static class Tab { String title; public int id; Tab(int id, String title){ this.id = id; this.title = title; } @Override public boolean equals(Object obj) { if(obj instanceof Tab){ return ((Tab)obj).id == id; }else{ return false; } } } } 

代码在我的Github Gist上 。