Después de descubrir qué métodos ViewPager son llamados por ViewPager y cuáles son para otros fines, se me ocurrió una solución. Lo presento aquí porque veo que mucha gente ha luchado con esto y no he visto ninguna otra respuesta relevante.
Primero, aquí está mi adaptador; Esperemos que los comentarios dentro del código sean suficientes:
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.
}
Y aquí hay algunos fragmentos de código que muestran cómo usar el adaptador.
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);
}
}
Finalmente, puede usar lo siguiente para su activity_main.xml
diseño:
<?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>
Estaba buscando una solución simple para eliminar las vistas del visor (sin fragmentos) dinámicamente. Por lo tanto, si tiene alguna información a la que pertenecen sus páginas, puede establecerla en Ver como etiqueta. Solo así (código del adaptador):
Solo necesita eliminar su información de mMessages y luego solicitar
notifyDataSetChanged()
su adaptador. Malas noticias no hay animación en este caso.fuente
Hay bastantes discusiones sobre este tema.
Aunque lo vemos a menudo, el uso
POSITION_NONE
no parece ser el camino a seguir, ya que es muy ineficiente en cuanto a memoria.Aquí en esta pregunta, deberíamos considerar usar el enfoque de Alvaro :
Aquí hay una respuesta SO con código basado en esta idea
fuente
Hice un programa similar. Espero que esto te ayude. En su primera actividad se pueden seleccionar cuatro datos de cuadrícula. En la siguiente actividad, hay un localizador de vistas que contiene dos páginas obligatorias y habrá 4 páginas más, que serán visibles correspondientes a los datos de la cuadrícula seleccionados.
Lo siguiente es la actividad principal MainActivity
Aquí TabFragment1, TabFragment2, etc.son fragmentos que se mostrarán en el visor. Y no estoy mostrando los diseños ya que están fuera del alcance de este proyecto.
MainActivity intentará Main2Activity Main2Activity
ViewPagerAdapter Viewpageradapter.class
Diseño para main2activity acticity_main2.xml
Espero que esto ayude a alguien ... Haga clic en el botón arriba si esto le ayudó
fuente
Aquí hay una solución alternativa a esta pregunta. Mi adaptador:
Código para eliminar y agregar dinámicamente
Después del consejo de Peri Hartman, comenzó a funcionar después de configurar el adaptador nulo de ViewPager y volver a colocar el adaptador después de que se eliminaran las vistas. Antes de esto, la página 0 no mostraba el contenido de su lista.
Gracias.
fuente
He creado una biblioteca de PagerAdapters personalizada para cambiar elementos en PagerAdapters dinámicamente.
Puede cambiar elementos dinámicamente como los siguientes utilizando esta biblioteca.
La biblioteca Thils también admite páginas creadas por Fragments.
fuente
Para eliminar puedes usar esto directamente:
fragment
es el fragmento que quieres eliminar.fuente
Encuentro una buena solución para este problema, esta solución puede hacer que funcione y no es necesario volver a crear Fragmentos.
Mi punto clave es:
Código fuente
El código está en mi Github Gist .
fuente