动态添加和删除视图到视图页面

(我想出了一个解决方案——请看我在下面回答部分的帖子。)

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

我已经读了无数的帖子和概述,但仍然缺少一些东西。以下是我认为自己理解的:

MainActivity 创建 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 本身吗?
  • IsViewFromObject 是做什么的? 首先,一个对象是如何与一个视图相关联的?
  • 当我添加或删除视图时,我是否应该调用 startUpdate 和 finishUdate?

谢谢。

186510 次浏览

在弄清楚 ViewPager 调用哪些 ViewPager 方法以及哪些方法用于其他目的之后,我想出了一个解决方案。我在这里介绍它,因为我看到很多人已经与这个斗争,我没有看到任何其他相关的答案。

首先,这是我的适配器; 希望代码中的注释足够了:

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>

这里有一个解决这个问题的替代方案。我的适配器:

    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);
}
}

动态删除和添加的代码

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


pagerAdapter.addPage(pass your fragment);

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

谢谢。

我正在寻找一个简单的解决方案,动态地从视图页面中删除视图(没有片段)。因此,如果您有一些信息,您的网页属于,您可以设置为查看作为标记。就像这样(适配器代码) :

@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()。坏消息是这里没有动画。

围绕这个话题有相当多的讨论

虽然我们经常看到它,使用 POSITION_NONE似乎不是作为 在内存方面是非常低效的。的方式去

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

setTag()方法 在实例化一个新视图时使用 instantiateItem() 可以使用 findViewWithTag()查找视图 你想要更新。

这是一个基于这个想法的 用密码回答

我也做过类似的项目。希望这个对你有帮助。它的第一个活动可以选择四个网格数据。在下一个活动中,有一个包含两个强制页面的视图分页器。还有4个页面将在那里,这将是可见的对应的网格数据选择。

以下是主要活动 主要活动

    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等都是要显示在视图页面上的片段。我不会展示布局,因为它们超出了这个项目的范围。

MainActivity 将意图使用 Main2Activity Main2活动

    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 类

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();
}
}

主要活动的布局 Act _ 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>

希望这将有助于某人... 请点击按钮,如果这对你有帮助

我已经创建了一个 自定义 PagerAdapters 库来动态更改 PagerAdapters 中的项目。

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

@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 库还支持由片段创建的页面。

要删除,可以直接使用:

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

fragment是要删除的片段。

我为这个问题找到了一个很好的解决方案,这个解决方案可以使它工作,而不需要重新创建片段。
我的重点是:

  1. 每次删除或添加选项卡(片段)时设置 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