Puedo usar el paginador de vista con vistas (no con fragmentos)

Estoy utilizando ViewPager para pasar b / w Fragments , pero ¿puedo usar ViewPager para deslizar b / w Views diseño simple xml?

Esta es mi página de Adapter para el ViewPager que se utiliza para deslizar entre Fragmentos:

 import java.util.List; import com.app.name.fragments.TipsFragment; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentTransaction; import android.view.ViewGroup; public class PageAdapter extends FragmentPagerAdapter { /** * */ List<Fragment> fragments; public PageAdapter(FragmentManager fm,List<Fragment> frags) { super(fm); fragments = frags; } @Override public Fragment getItem(int arg0) { // TODO Auto-generated method stub return TipsFragment.newInstance(0, 0); } @Override public int getCount() { // TODO Auto-generated method stub return 4; } @Override public void destroyItem(ViewGroup container, int position, Object object) { FragmentManager manager = ((Fragment) object).getFragmentManager(); FragmentTransaction trans = manager.beginTransaction(); trans.remove((Fragment) object); trans.commit(); super.destroyItem(container, position, object); } } 

Y este es mi fragmento de la punta:

 public class TipsFragment extends Fragment { public static TipsFragment newInstance(int image,int content) { TipsFragment fragment = new TipsFragment(); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.tip_layout, null); return view; } } 

¿Cómo puedo modificar mi código para trabajar con Views en lugar de Fragment?

Necesita anular estos dos métodos en lugar de getItem()

 @Override public Object instantiateItem(ViewGroup collection, int position) { View v = layoutInflater.inflate(...); ... collection.addView(v,0); return v; } @Override public void destroyItem(ViewGroup collection, int position, Object view) { collection.removeView((View) view); } 

Utilice este ejemplo

Puede utilizar un único diseño XML que anida las vistas de los niños.

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/page_one" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:text="PAGE ONE IN" android:layout_width="match_parent" android:layout_height="match_parent" android:textColor="#fff" android:textSize="24dp"/> </LinearLayout> <LinearLayout android:id="@+id/page_two" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:text="PAGE TWO IN" android:layout_width="match_parent" android:layout_height="match_parent" android:textColor="#fff" android:textSize="24dp"/> </LinearLayout> </android.support.v4.view.ViewPager> </LinearLayout> 

PERO … usted necesita manejar esto con un adaptador también. Aquí devuelve el ID de la vista encontrada sin inflar ningún otro diseño.

 class WizardPagerAdapter extends PagerAdapter { public Object instantiateItem(ViewGroup collection, int position) { int resId = 0; switch (position) { case 0: resId = R.id.page_one; break; case 1: resId = R.id.page_two; break; } return findViewById(resId); } @Override public int getCount() { return 2; } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == ((View) arg1); } } 

// Establecer el adaptador ViewPager

 WizardPagerAdapter adapter = new WizardPagerAdapter(); ViewPager pager = (ViewPager) findViewById(R.id.pager); pager.setAdapter(adapter); 

Sobre la base de las respuestas anteriores, hice la siguiente clase para lograr eso de una manera adecuada y clara (espero):

 public class MyViewPagerAdapter extends PagerAdapter { ArrayList<ViewGroup> views; LayoutInflater inflater; public MyViewPagerAdapter(ActionBarActivity ctx){ inflater=LayoutInflater.from(ctx); //instantiate your views list views=new ArrayList<ViewGroup>(5); } /** * To be called by onStop * Clean the memory */ public void release(){ views.clear(); views=null; } /** * Return the number of views available. */ @Override public int getCount() { return 5; } /** * Create the page for the given position. The adapter is responsible * for adding the view to the container given here, although it only * must ensure this is done by the time it returns from * {@link #finishUpdate(ViewGroup)}. * * @param container The containing View in which the page will be shown. * @param position The page position to be instantiated. * @return Returns an Object representing the new page. This does not * need to be a View, but can be some other container of the page.,container */ public Object instantiateItem(ViewGroup container, int position) { ViewGroup currentView; Log.e("MyViewPagerAdapter","instantiateItem for "+position); if(views.size()>position&&views.get(position)!=null){ Log.e("MyViewPagerAdapter","instantiateItem views.get(position) "+views.get(position)); currentView=views.get(position); }else{ Log.e("MyViewPagerAdapter","instantiateItem need to create the View"); int rootLayout=R.layout.view_screen; currentView= (ViewGroup) inflater.inflate(rootLayout,container,false); ((TextView)currentView.findViewById(R.id.txvTitle)).setText("My Views "+position); ((TextView)currentView.findViewById(R.id.btnButton)).setText("Button"); ((ImageView)currentView.findViewById(R.id.imvPicture)).setBackgroundColor(0xFF00FF00); } container.addView(currentView); return currentView; } /** * Remove a page for the given position. The adapter is responsible * for removing the view from its container, although it only must ensure * this is done by the time it returns from {@link #finishUpdate(ViewGroup)}. * * @param container The containing View from which the page will be removed. * @param position The page position to be removed. * @param object The same object that was returned by * {@link #instantiateItem(View, int)}. */ @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View)object); } /** * Determines whether a page View is associated with a specific key object * as returned by {@link #instantiateItem(ViewGroup, int)}. This method is * required for a PagerAdapter to function properly. * * @param view Page View to check for association with <code>object</code> * @param object Object to check for association with <code>view</code> * @return true if <code>view</code> is associated with the key object <code>object</code> */ @Override public boolean isViewFromObject(View view, Object object) { return view==((View)object); } } 

Y tienes que configurarlo en tu actividad:

 public class ActivityWithViewsPaged extends ActionBarActivity { /** * The page Adapter : Manage the list of views (in fact here, it's fragments) * And send them to the ViewPager */ private MyViewPagerAdapter pagerAdapter; /** * The ViewPager is a ViewGroup that manage the swipe from left to right to left * Like a listView with a gesture listener... */ private ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_with_views); //Find the viewPager viewPager = (ViewPager) super.findViewById(R.id.viewpager); //instanciate the PageAdapter pagerAdapter=new MyViewPagerAdapter(this); // Affectation de l'adapter au ViewPager viewPager.setAdapter(pagerAdapter); viewPager.setClipToPadding(false); viewPager.setPageMargin(12); //Add animation when the page are swiped //this instanciation only works with honeyComb and more //if you want it all version use AnimatorProxy of the nineoldAndroid lib //@see:http://stackoverflow.com/questions/15767729/backwards-compatible-pagetransformer if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){ viewPager.setPageTransformer(true, new PageTransformer()); } } @Override protected void onStop() { super.onStop(); pagerAdapter.release(); } 

Donde los archivos xml son obvios view_screen.xml:

 <xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/screen" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/txvTitle" android:layout_width="wrap_content" android:layout_gravity="center" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" android:shadowColor="#FF00FF" android:shadowDx="10" android:shadowDy="10" android:shadowRadius="5" android:textSize="32dp" android:textStyle="italic" android:background="#FFFFF000"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFFF00F0"> <TextView android:id="@+id/txvLeft" android:layout_width="wrap_content" android:layout_gravity="left" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1"/> <TextView android:id="@+id/txvRight" android:layout_width="wrap_content" android:layout_gravity="right" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp"/> </LinearLayout> <Button android:id="@+id/btnButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"/> <ImageView android:id="@+id/imvPicture" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center"/> </LinearLayout> 

Y ActivtyMain tiene la siguiente disposición:

 <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingLeft="24dp" android:paddingRight="24dp" android:id="@+id/viewpager" android:background="#FF00F0F0"> </android.support.v4.view.ViewPager> 

Muchas gracias a Brian y Nicholas por su respuesta, espero agregar alguna información más clara y hightlight algunas buenas prácticas para esta característica.

Hemos ViewPager una subclase muy simple del ViewPager que usamos a veces.

 /** * View pager used for a finite, low number of pages, where there is no need for * optimization. */ public class StaticViewPager extends ViewPager { /** * Initialize the view. * * @param context * The application context. */ public StaticViewPager(final Context context) { super(context); } /** * Initialize the view. * * @param context * The application context. * @param attrs * The requested attributes. */ public StaticViewPager(final Context context, final AttributeSet attrs) { super(context, attrs); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); // Make sure all are loaded at once final int childrenCount = getChildCount(); setOffscreenPageLimit(childrenCount - 1); // Attach the adapter setAdapter(new PagerAdapter() { @Override public Object instantiateItem(final ViewGroup container, final int position) { return container.getChildAt(position); } @Override public boolean isViewFromObject(final View arg0, final Object arg1) { return arg0 == arg1; } @Override public int getCount() { return childrenCount; } @Override public void destroyItem(final View container, final int position, final Object object) {} }); } } 

Esta clase no necesita un adaptador, ya que cargará las vistas desde el diseño. Para poder usar sus proyectos, solo úselo en lugar de android.support.v4.view.ViewPager .

Todas las cosas de lujo seguirán funcionando, pero no es necesario que te molesten los adaptadores.

Me gustaría elaborar sobre @Nicholas respuesta, puede obtener las vistas por id o si se añaden dinámicamente sólo obtener la vista directamente dada su posición

 class WizardPagerAdapter extends PagerAdapter { public Object instantiateItem(View collection, int position) { View v = pager.getChildAt(position); return v; } @Override public int getCount() { return 3; } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == ((View) arg1); } } 

Quisiera agregar mi solución aquí. Dado que no es necesario utilizar fragmentos, puede crear un PagerAdapter que PagerAdapter views lugar de fragments al ViewPager .

Extienda PagerAdapter lugar de FragmentPagerAdapter

 public class CustomPagerAdapter extends PagerAdapter { private Context context; public CustomPagerAdapter(Context context) { super(); this.context = context; } @Override public Object instantiateItem(ViewGroup collection, int position) { LayoutInflater inflater = LayoutInflater.from(context); View view = null; switch (position){ case 0: view = MemoryView.getView(context, collection); break; case 1: view = NetworkView.getView(context, collection); break; case 2: view = CpuView.getView(context, collection); break; } collection.addView(view); return view; } @Override public int getCount() { return 3; } @Override public boolean isViewFromObject(View view, Object object) { return view==object; } @Override public void destroyItem(ViewGroup collection, int position, Object view) { collection.removeView((View) view); } } 

Ahora necesita definir tres clases que devolverán las views que se viewpager en el viewpager . Similar a CpuView tendrá clases de MemoryView y NetworkView . Cada uno de ellos inflar sus respectivos diseños.

 public class CpuView { public static View getView(Context context, ViewGroup collection) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context .LAYOUT_INFLATER_SERVICE); return inflater.inflate(R.layout.debugger_cpu_layout, collection, false); } } 

Y finalmente un diseño que se inflará en cada una de las vistas

  <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="#000000" android:text="CPU"/> </LinearLayout> 

PS: La razón por la que escribí esta respuesta es porque todas las soluciones proporcionadas aquí parecen estar funcionando bien, pero están inflando los diseños en la propia clase PagerAdapter. Para grandes proyectos se vuelve difícil de mantener si su es un montón de código relacionado con los diseños inflados. Ahora, en este ejemplo, todas las vistas tienen clases separadas y diseños separados. Así que el proyecto se puede mantener fácilmente.

  • Cómo colocar el botón de acción flotante exclusivamente en un fragmento sólo en el diseño de la pestaña
  • La imagen no se muestra en ImageViewZoom
  • No se puede establecer la propiedad en un fragmento con varias instancias
  • Cómo carga fragmento en ViewPager sólo cuando su seleccionado
  • Adaptador ViewPager de Android: force getPageWidth cada vez
  • ViewPager FragmentPagerAdapter Nullpointer
  • ¿Cómo agregar una página al principio de ViewPager?
  • Barra de acción Sherlock: las pestañas no cambiarán en el paisaje al pasar
  • OnPageSelected no se activa cuando se llama a setCurrentItem (0)
  • CoordinatorLayout + AppbarLayout + Viewpager no cambia el tamaño del diseño secundario
  • Cómo configurar la altura de la barra de herramientas de Collapsing
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.