Intereting Posts
Android – связь между двумя устройствами Бинарная строка XML-файла # 8: ошибка раздувания фрагмента класса, карты Google Широковещательный приемник для пропущенного вызова в android Android Toast перемещается по экрану Какой тип приложений для Android наиболее сложно поддерживать (фрагментация) Service.onDestroy () вызывается сразу после создания, в любом случае Служба выполняет свою работу JavaScript: отслеживание выбора изменений в Firefox для Android Как я могу запустить командную строку FFMPEG и принять несколько каналов (видео и аудио) без блокировки на первом входе? Android: Как работать с фоновым потоком? Как отключить proguard для создания моего Android-приложения? Какое значение имеет местоположение каждого Android.Address? Ошибка android.content.res.Resources $ NotFoundException: Файл из ресурса макета типа xml ID # 0x102000a Как создать пакет андроидной версии релиза (aar) в Android Studio (не отлаживать) Производительность Android: добавление вида программно и установка представления в GONE / VISIBLE Иммерсивный полноэкранный режим ниже 4.4

Динамически добавлять и удалять вид на просмотрщик

(Я понял решение – см. Мой пост в разделе «Ответ» ниже).

В моем приложении пользователь начнет с одного взгляда на свои данные. Я хотел бы добавить 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 и finalUdate при добавлении или удалении просмотров?

Благодарю.

Solutions Collecting From Web of "Динамически добавлять и удалять вид на просмотрщик"

После выяснения того, какие методы 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> 

Я искал простое решение для динамического удаления представлений из 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() для вашего адаптера. Плохая новость, в этом случае анимации нет.

В этой теме обсуждается довольно много дискуссий

  • ViewPager PagerAdapter не обновляет вид
  • Обновлять ViewPager динамически?
  • Удаление фрагментов из FragmentStatePagerAdapter

Хотя мы часто это видим, использование POSITION_NONE , похоже, не так, как если бы оно было очень неэффективным по памяти.

Здесь, в этом вопросе, мы должны рассмотреть подход Альваро :

… является методом setTag() в instantiateItem() при создании нового представления. Затем вместо использования notifyDataSetChanged() вы можете использовать findViewWithTag() чтобы найти представление, которое хотите обновить.

Вот ответ SO с кодом, основанным на этой идее

Я сделал аналогичную программу. Надеюсь, это поможет вам. В своем первом действии можно выбрать четыре сетки. В следующем действии есть пейджер представления, который содержит две обязательные страницы. И там будет еще 4 страницы, которые будут видны, соответствующие выбранным данным сетки.

Ниже приводится mainactivty 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. И я не показываю макеты, так как они выходят за рамки этого проекта.

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> 

Надеюсь, это поможет кому-то … Нажмите кнопку, пожалуйста, если это вам помогло

Я создал специальную библиотеку 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 также поддерживает страницы, созданные Фрагментами.

Вот альтернативное решение этого вопроса. Мой адаптер:

  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, он начал работать после того, как я установил нулевой адаптер ViewPager и снова установил адаптер после удаления представлений. До этого страница 0 не показывала содержимое списка.

Благодарю.

Для удаления вы можете использовать это непосредственно:

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

fragment – фрагмент, который вы хотите удалить.

Я нахожу хорошее решение для этой проблемы, это решение может заставить его работать и не нужно воссоздавать фрагменты.
Мой ключевой момент:

  1. Настроить ViewPager каждый раз, когда вы удаляете или добавляете вкладку (фрагмент).
  2. Переопределите метод getItemId, верните определенный идентификатор, а не позицию.

Исходный код

 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 .