studio programacion herramientas fundamentos con avanzado aplicaciones android horizontal-scrolling android-viewpager

programacion - manual de android en pdf



Android: desplazamiento horizontal de mĂșltiples elementos visibles (7)

EDITAR: ver mi propia respuesta para una solución fácil

IMPORTANTE : Bounty se ofrece para una manera clara de modificar ViewPager para satisfacer el escenario descrito a continuación. Por favor, no ofrezca HorizontalScrollView - Necesito un escenario de ciclo de vida lleno de Fragmentos cubierto

Necesito implementar el desplazamiento horizontal de vistas basadas en Fragments en las que un elemento está en el centro y los elementos a la derecha / izquierda son parcial o totalmente visibles. ViewPager es adecuado para la tarea, ya que se centra en mostrar un elemento en cada momento.

Para que sea más fácil de entender a continuación, hay un boceto rápido en el que los elementos 1, 5 y 6 están fuera del área visible. Y quiero que este número visible se pueda configurar, por ejemplo, en la vista vertical, solo mostraré 2 (o posiblemente solo uno) elementos.

No estoy intentando encajar decir 3 elementos en la pantalla, siempre y cuando se muestre el elemento central, otros pueden recortarse. En la pantalla pequeña, está bien tener 1 elemento central y, a medida que la pantalla crece en tamaño, se mostrarán los elementos múltiples (recortada está bien)

Entiendo que esto parece una galería pero, una vez más, los elementos no son imágenes simples, sino Fragments con una lista verticalmente desplazable en cada fragmento

PD Encontró esta publicación de blog por @Commonsware que enumera 3 enfoques diferentes . Por mi necesidad, me gusta # 3


Además de la segunda respuesta de MrZander, eche un vistazo a este https://.com/a/2655740/935075


Estamos haciendo algo muy parecido a lo que está describiendo al usar una Gallery con Fragments , y un adaptador de galería que amplía BaseAdapter . Recomiendo ir con una galería para lograr su objetivo (también utilizamos un ViewPager para la vista donde no necesitamos ver los otros fragmentos).


Este tiene una respuesta sorprendentemente fácil, ni siquiera estoy seguro de por qué no fue publicado de inmediato. Todo lo que necesitaba hacer para obtener el efecto exacto era anular PagerAdapter#getPageWidth método PagerAdapter#getPageWidth . Por defecto, devuelve 1, pero si lo configura en 0.5 obtendrá 2 páginas, 0.33 le dará 3, etc. Dependiendo del ancho del separador entre los elementos del buscapersonas, es posible que tenga que disminuir ligeramente el valor.

Vea el siguiente fragmento:

@Override public float getPageWidth(final int position) { // this will have 3 pages in a single view return 0.32f; }


Puedo pensar en dos formas de implementar esto posiblemente.

  1. Por un ViewSwitcher . Aquí hay un excelente video de YouTube que muestra cómo funciona con un onGestureListener . Sin embargo, no estoy seguro si esto funcionará con vistas múltiples como muestra su imagen.

  2. Como alternativa, puede usar un HorizontalScrollView . Sin embargo, esto a menudo causa problemas si tiene un ScrollView dentro de otro, ¡pero puede valer la pena intentarlo!

Déjame saber cómo va, ¡buena suerte!


Si desea extender ViewPager, simplemente anule el método de dibujo y establezca OffscreenPageLimit (int limit). Pero, recomiendo usar FragmentPageAdapter si los fragmentos son complejos.

Puede verificar el código fuente here o si desea verificar el que está en el paquete de soporte, puede hacerlo here .


Una vez escribí algo similar como plantilla. En mi ejemplo, puedo desplazarme con los botones hacia arriba, hacia abajo y hacia los lados. Puede modificarlo un poco para cumplir sus requisitos. En mi ejemplo, tengo 4 vistas organizadas de esta manera:

1 2
3 4

Se parece a esto. En la imagen, me desplazo desde la vista 1 a la derecha para ver 2:

El código consiste en este xml:

<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_height="350sp" android:layout_width="320sp"> <LinearLayout android:id="@+id/viewContainer" android:background="#CCCCCC" android:layout_width="640sp" android:layout_height="700sp"> </LinearLayout> </LinearLayout> <TableLayout android:id="@+id/tableLayout" android:layout_width="320sp" android:layout_height="fill_parent" android:stretchColumns="1" android:gravity="bottom" android:layout_alignParentBottom="true"> <TableRow android:background="#333333" android:gravity="bottom"> <Button android:id="@+id/btnUp" android:layout_width="60sp" android:layout_height="50sp" android:text="Lift U" /> <Button android:layout_width="60sp" android:layout_height="50sp" android:visibility="invisible" /> <Button android:layout_width="60sp" android:layout_height="50sp" android:visibility="invisible" /> <Button android:id="@+id/btnScreenUp" android:layout_width="60sp" android:layout_height="50sp" android:layout_gravity="right" android:text="Scrn U" /> </TableRow> <TableRow android:background="#444444" android:layout_gravity="right"> <Button android:id="@+id/btnDown" android:layout_width="60sp" android:layout_height="50sp" android:text="Lift D" /> <Button android:id="@+id/btnEnter" android:layout_width="60sp" android:layout_height="50sp" android:text="Enter" /> <Button android:id="@+id/btnScreenLeft" android:layout_width="60sp" android:layout_height="50sp" android:layout_gravity="right" android:text="Scrn L" /> <Button android:id="@+id/btnScreenDown" android:layout_width="60sp" android:layout_height="50sp" android:layout_gravity="right" android:text="Scrn D" /> <Button android:id="@+id/btnScreenRight" android:layout_width="60sp" android:layout_height="50sp" android:layout_gravity="right" android:text="Scrn R" /> </TableRow> </TableLayout> </FrameLayout>

y este código de Java:

import android.app.Activity; import android.os.Bundle; import android.util.DisplayMetrics; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; public class ViewSwitcherTest extends Activity { private TextView view1, view2, view3, view4; private Button btnUp, btnEnter, btnDown, btnScreenDown, btnScreenUp, btnScreenLeft, btnScreenRight; private LinearLayout viewContainer; // private TableLayout tableLayout; private LinearLayout.LayoutParams layoutParams; private DisplayMetrics metrics = new DisplayMetrics(); private int top = 0, left = 0; private float density = 1.0f; // private ViewSwitcher switcher; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindowManager().getDefaultDisplay().getMetrics(metrics); density = metrics.density; setContentView(R.layout.main); // Buttons btnEnter = (Button)findViewById(R.id.btnEnter); btnUp = (Button)findViewById(R.id.btnUp); btnDown = (Button)findViewById(R.id.btnDown); btnScreenDown = (Button)findViewById(R.id.btnScreenDown); btnScreenUp = (Button)findViewById(R.id.btnScreenUp); btnScreenLeft = (Button)findViewById(R.id.btnScreenLeft); btnScreenRight = (Button)findViewById(R.id.btnScreenRight); // -------- // tableLayout = (TableLayout)findViewById(R.id.tableLayout); view1 = new TextView(this); view1.setBackgroundResource(R.drawable.view1); view1.setHeight((int)(350*density)); view1.setWidth((int)(320*density)); view1.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL); layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(left, top, 0, 0); viewContainer = (LinearLayout)findViewById(R.id.viewContainer); viewContainer.addView(view1, layoutParams); //Add 2nd view view2 = new TextView(this); view2.setBackgroundResource(R.drawable.view2); view2.setHeight((int)(350*density)); view2.setWidth((int)(320*density)); view2.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL); layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(left, top, 0, 0); viewContainer.addView(view2, layoutParams); //Add 3rd view view3 = new TextView(this); view3.setBackgroundResource(R.drawable.view3); view3.setHeight((int)(350*density)); view3.setWidth((int)(320*density)); view3.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL); top += 350*density; left += 640*density*(-1); layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(left, top, 0, 0); viewContainer.addView(view3, layoutParams); //add 4th view view4 = new TextView(this); view4.setBackgroundResource(R.drawable.view4); view4.setHeight((int)(350*density)); view4.setWidth((int)(320*density)); view4.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL); top += 0; left += 640*density; layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(left, top, 0, 0); viewContainer.addView(view4, layoutParams); btnEnter.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // Quit the application for now finish(); } }); btnScreenLeft.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { viewContainer.scrollBy(-10,0); } }); btnScreenRight.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { viewContainer.scrollBy(10,0); } }); btnScreenUp.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { viewContainer.scrollBy(0,-10); } }); btnScreenDown.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { viewContainer.scrollBy(0,10); } }); // view1.setOnKeyListener(new OnKeyListener() { // @Override // public boolean onKey(View v, int keyCode, KeyEvent event) { // if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) // viewContainer.scrollBy(0,10); // return true; // } // }); } }

Los grandes números en cada pantalla son imágenes de fondo negro con esos números pintados en él. (No lo publiqué aquí porque probablemente modificará el código de todos modos).


Consulte esta publicación de blog sobre cómo escribir una vista de desplazamiento horizontal personalizada para lograr algo similar. El ejemplo tiene solo una pantalla visible a la vez, pero debería poder modificarla fácilmente según sus necesidades.