Estoy tratando de crear una interfaz de usuario para mi aplicación para Android que contiene un verticalmente desplazable página de desplazable horizontalmente carruseles (algo así como lo que la aplicación de Netflix se hace). Cómo es este tipo de comportamiento se logra?

Una aplicación de base sería suficiente para que me inició. Hay un par de requisitos para la interfaz de usuario, que voy a incluir aquí por referencia, ya que es posible el impacto de qué clases o bibliotecas puedo usar.

1) el desplazamiento Vertical entre los carruseles debe ser suave, pero cuando el usuario suelta, la interfaz de usuario debe «ajustar a» la más cercana carrusel (por lo que el usuario está siempre en un carrusel de la fila, no entre dos carruseles).

2) el desplazamiento Horizontal en un carrusel debe ser suave, pero cuando el usuario suelta, la interfaz de usuario debe «ajustar a» el más cercano al punto en el carrusel.

3) Debe ser posible la superposición de información adicional sobre un elemento en el carrusel

4) interfaz de usuario debe ser adaptable a cualquier tamaño de pantalla.

5) Debe ser navegable con las teclas de flecha (para pantalla táctil-menos dispositivos)

6) Debería funcionar en una amplia gama de versiones de Android (posiblemente a través de la biblioteca de compatibilidad)

7) Debe ACEPTAR para usar en un open-source de la aplicación bajo licencia GPL

Aceptable respuestas NO tienen que cumplir con todos estos requisitos. Como mínimo, una buena respuesta debe involucrar a navegar por varios carruseles (frente a sólo un carrusel).

Aquí es una maqueta de lo que básicamente estoy imaginando (soy flexible, no tiene que mirar como esta.. el punto es sólo para aclarar lo que estoy hablando, cada fila contiene una gran cantidad de elementos que podrían desplazarse a izquierda y derecha, y la totalidad de la página podría ser desplazado hacia arriba y hacia abajo)

Cómo crear desplazable página de carruseles en Android?

InformationsquelleAutor paulscode | 2014-11-22

4 Comentarios

  1. 47

    Idea Principal

    Con el fin de tener un diseño flexible y tener ilimitado de elementos puede crear un RecyclerView como una raíz que ver con un LinearLayoutManager.VERTICAL como un LayoutManager. para cada fila puede poner otro RecyclerView pero ahora con un LinearLayoutManager.HORIZONTAL como un LayoutManager.

    Resultado

    Cómo crear desplazable página de carruseles en Android?

    Fuente

    Código

    Requisitos

    1) el desplazamiento Vertical entre los carruseles debe ser suave, pero cuando
    el usuario libera, la interfaz de usuario debe «ajustar a» la más cercana carrusel (por lo que el
    el usuario es siempre en un carrusel de la fila, no entre dos carruseles).

    2) el desplazamiento Horizontal en un carrusel debe ser suave, pero cuando el usuario
    de prensa, la interfaz de usuario debe «ajustar a» el más cercano al punto en el carrusel.

    Con el fin de lograr los he usado OnScrollListener y cuando los estados se va SCROLL_STATE_IDLE puedo comprobar la parte superior e inferior de las vistas para ver cuál de ellos tiene más visibles de la región, a continuación, desplácese a la posición. para cada una de las filas, yo lo hago para vistas izquierda y derecha de cada fila adaptador. De esta manera siempre un lado de su carruseles o filas de ajuste. por ejemplo, si la parte superior está equipado en la parte inferior no es, o viceversa. Yo creo que si juegas un poco más se puede lograr eso, pero usted debe saber la dimensión de la ventana y cambiar la dimensión de los carruseles en tiempo de ejecución.

    3) Debe ser posible la superposición de información adicional sobre un elemento
    en el carrusel de

    Si utiliza RelativeLayout o FrameLayout como una raíz de vista de cada artículo que usted puede poner la información en la parte superior de uno al otro. como se puede ver los números están en la parte superior de las imágenes.

    4) interfaz de usuario debe ser adaptable a cualquier tamaño de pantalla.

    si usted sabe cómo el soporte de múltiples tamaño de la pantalla que usted puede hacer tan fácilmente, si no sabes leer el documento.
    Soporte De Múltiples Pantallas

    5) Debe ser navegable con las teclas de flecha (para pantalla táctil-menos
    los dispositivos)

    usar debajo de la función

    mRecyclerView.scrollToPosition(position);

    6) Debería funcionar en una amplia gama de versiones de Android (posiblemente a través de la
    el apoyo de la biblioteca)

    import android.apoyo.v7.widget.RecyclerView;

    7) Debe ACEPTAR para usar en un open-source de la aplicación bajo licencia GPL

    Aceptar

    feliz codificación!!

    • Esta es una excelente y muy completa respuesta. Gracias!
    • Aunque hay muchas respuestas aceptables aquí, he decidido aceptar la suya. No sólo las respuestas a la pregunta original, bien, pero las direcciones de cada uno de mis requisitos adicionales, y toma en consideración la capacidad de mostrar ilimitado de elementos (que yo no había considerado cuando originalmente la publicación de la pregunta). Voy a seguir con mi promesa para el doble de la recompensa una vez más después de la adjudicación de este en un par de días.
    • usted es siempre bienvenido!!
    • darle la recompensa es que termina en 22 hrs
    • hecho. (Habría auto-aplicado, de todos modos si se había agotado, ya que es la única 2+ respuesta dada después de los 100 rep recompensa fue publicado)
    • ¿Alguien me sugiere cómo conseguir el onitem clic referencia de la baldosa de nuevo a la Principal Activiy. Estoy atrapado aquí.

  2. 6

    Puede utilizar ListView personalizado OnTouchListener (para el ajuste de los elementos) para el desplazamiento vertical y TwoWayGridView de nuevo con una costumbre OnTouchListener (para el ajuste de los elementos)

    Cómo crear desplazable página de carruseles en Android?

    main.xml

    <ListView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/containerList"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:background="#E8E8E8"
        android:divider="@android:color/transparent"
        android:dividerHeight="16dp" />

    list_item_hgrid.xml

    <com.jess.ui.TwoWayGridView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/grid"
        android:layout_width="match_parent"
        android:layout_height="160dp"
        android:layout_marginBottom="16dp"
        app:cacheColorHint="#E8E8E8"
        app:columnWidth="128dp"
        app:gravity="center"
        app:horizontalSpacing="16dp"
        app:numColumns="auto_fit"
        app:numRows="1"
        app:rowHeight="128dp"
        app:scrollDirectionLandscape="horizontal"
        app:scrollDirectionPortrait="horizontal"
        app:stretchMode="spacingWidthUniform"
        app:verticalSpacing="16dp" />

    Y el código de la Actividad será algo como lo siguiente

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test);
    
        ListView containerList = (ListView) findViewById(R.id.containerList);
        containerList.setAdapter(new DummyGridsAdapter(this));
        containerList.setOnTouchListener(mContainerListOnTouchListener);
    }
    
    private View.OnTouchListener mContainerListOnTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_UP:
                    View itemView = ((ListView) view).getChildAt(0);
                    int top = itemView.getTop();
                    if (Math.abs(top) >= itemView.getHeight() / 2) {
                        top = itemView.getHeight() - Math.abs(top);
                    }
    
                    ((ListView) view).smoothScrollBy(top, 400);
            }
    
            return false;
        }
    };

    Y aquí está la prueba de adaptadores de

    private static class DummyGridsAdapter extends BaseAdapter {
    private Context mContext;
    private TwoWayGridView[] mChildGrid;
    public DummyGridsAdapter(Context context) {
    mContext = context;
    mChildGrid = new TwoWayGridView[getCount()];
    for (int i = 0; i < mChildGrid.length; i++) {
    mChildGrid[i] = (TwoWayGridView) LayoutInflater.from(context).
    inflate(R.layout.list_item_hgrid, null);
    mChildGrid[i].setAdapter(new DummyImageAdapter(context));
    mChildGrid[i].setOnTouchListener(mChildGridOnTouchListener);
    }
    }
    @Override
    public int getCount() {
    return 8;
    }
    @Override
    public Object getItem(int position) {
    return position;
    }
    @Override
    public long getItemId(int position) {
    return 0;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    return mChildGrid[position];
    }
    private View.OnTouchListener mChildGridOnTouchListener = new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_UP:
    View itemView = ((TwoWayGridView) view).getChildAt(0);
    int left = itemView.getLeft();
    if (Math.abs(left) >= itemView.getWidth() / 2) {
    left = itemView.getWidth() - Math.abs(left);
    }
    ((TwoWayGridView) view).smoothScrollBy(left, 400);
    }
    return false;
    }
    };
    }
    private static class DummyImageAdapter extends BaseAdapter {
    private Context mContext;
    private final int mDummyViewWidthHeight;
    public DummyImageAdapter(Context context) {
    mContext = context;
    mDummyViewWidthHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 128,
    context.getResources().getDisplayMetrics());
    }
    @Override
    public int getCount() {
    return 16;
    }
    @Override
    public Object getItem(int position) {
    int component = (getCount() - position - 1) * 255 / getCount();
    return Color.argb(255, 255, component, component);
    }
    @Override
    public long getItemId(int position) {
    return 0;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView = new ImageView(mContext);
    imageView.setBackgroundColor((Integer) getItem(position));
    imageView.setLayoutParams(new TwoWayGridView.LayoutParams(mDummyViewWidthHeight, mDummyViewWidthHeight));
    return imageView;
    }
    }
    • Otra gran respuesta detallada! Voy a probar y comparar todas las sugerencias en esta noche, y decidir cual se ajusta a mis necesidades mejor.
  3. 2

    Sugiero que el Reciclador de vista.

    Puede crear horizontal y vertical de la lista o gridviews. En mi opinión el viewpager puede llegar a ser complicado a veces.

    Estoy trabajando en un video en demanda de la aplicación y esto me salvó.

    En tu caso va a ser fácil de configurar. Voy a dar algo de código.

    Se necesitan los siguientes:


    Vista XML – Donde la papelera de diseño es declarado.

    Adaptador – Usted tendrá una vista para rellenar el adaptador y llenar el recycleview.

    La creación de la vista

    <android.support.v7.widget.RecyclerView
    android:id="@+id/recycle_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="none"
    android:orientation="horizontal"
    android:gravity="center"
    android:overScrollMode="never"/>

    Declarar este donde desea que el carrusel para mostrar.

    Próximo desea crear el adaptador:

    public class HorizontalCarouselItemAdapter extends RecyclerView.Adapter<HorizontalCarouselItemAdapter.ViewHolder> {
    List<objects> items;
    int itemLayout;
    public HorizontalCarouselItemAdapter(Context context, int itemLayout, List<objects> items) {
    this.context = context;
    this.itemLayout = itemLayout;
    this.items = items;
    }
    @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(itemLayout, parent, false);
    return new ViewHolder(v);
    }
    @Override public void onBindViewHolder(final ViewHolder holder, final int position) {
    this.holders = holder;
    final GenericAsset itemAdapter = items.get(position);
    holder.itemImage.setDrawable //manipulate variables here
    }
    @Override public int getItemCount() {
    return items.size();
    }
    public static class ViewHolder extends RecyclerView.ViewHolder {
    public ImageView itemImage;
    public ViewHolder(View itemView) {
    super(itemView);
    itemImage = (ImageView) itemView.findViewById(R.id.carousel_cell_holder_image);
    }
    }

    Este es donde se alimentan los datos para el adaptador para rellenar cada carrusel elemento.

    Finalmente declarar y llamar a la adaptador:

    recyclerView = (RecyclerView)findViewById(R.id.recycle_view);
    ListLayoutManager manager = new ListLayoutManager(getApplication(), ListLayoutManager.Orientation.HORIZONTAL);
    recyclerView.setLayoutManager(manager);
    CustomAdpater adapter = new CustomAdapter(getApplication(), data);
    recyclerView.setAdapter(adapter);

    Puede crear un listview con la papelera de vistas a lograr lo que desea.

    Esta clase es ideal para el desplazamiento suave y optimización de la memoria.

    Este es el link para que:

    https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html

    Espero que esto ayude.

    • Gracias por la respuesta detallada. Definitivamente voy a revisar esto!
    • No se preocupe si usted tiene preguntas sobre este hágamelo saber!
  4. 2

    Puede utilizar un ScrollView como padre dentro de que ScrollView lugar un Vertical LinearLayout en for loop inflar un diseño que consisten en coverflow para carrusel efecto

    • Que es un buen ejemplo de adición de efectos a un carrusel. Yo estoy un poco más buscando un efecto en el que la página seleccionada es ligeramente más grande que la anterior/ siguiente páginas, en lugar de utilizar las rotaciones como este. Pero aún así es un excelente ejemplo de la referencia. Gracias!
    • ok voy a tratar de aplicar que si había conseguido, le dejaremos saber

Dejar respuesta

Please enter your comment!
Please enter your name here