android studio - ¿Cómo construir un ListView horizontal con RecyclerView?





ejemplo lista (9)


Con el lanzamiento de la biblioteca RecyclerView, ahora puede alinear una lista de imágenes que se enlazan con el texto fácilmente. Puede usar LinearLayoutManager para especificar la dirección en la que desea orientar su lista, ya sea vertical u horizontal como se muestra a continuación.

Puedes descargar una whats-online.info/science-and-tutorials/87/… completa whats-online.info/science-and-tutorials/87/…

Necesito implementar una vista de lista horizontal en mi aplicación de Android. Investigué un poco y encontré ¿Cómo puedo hacer un ListView horizontal en Android? y ListView horizontal en Android? sin embargo, estas preguntas se hicieron antes de que se lanzara Recyclerview. ¿Hay una mejor manera de implementar esto ahora con Recyclerview?




Ejemplo completo

La única diferencia real entre un RecyclerView vertical y uno horizontal es cómo configura LinearLayoutManager . Aquí está el fragmento de código. El ejemplo completo está abajo.

LinearLayoutManager horizontalLayoutManagaer = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(horizontalLayoutManagaer);

Este ejemplo más completo se basa en mi respuesta RecyclerView vertical .

Actualizar dependencias de Gradle

Asegúrese de que las siguientes dependencias estén en su aplicación gradle.build file:

implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'

Puede actualizar los números de versión a lo que sea más actual .

Crear diseño de actividad

Agregue el RecyclerView a su diseño xml.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rvAnimals"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

Crear diseño de elemento

Cada elemento de nuestro RecyclerView tendrá una única View color sobre un TextView . Crear un nuevo archivo de recursos de diseño.

recyclerview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp">

    <View
        android:id="@+id/colorView"
        android:layout_width="100dp"
        android:layout_height="100dp"/>

    <TextView
        android:id="@+id/tvAnimalName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"/>

</LinearLayout>

Crear el adaptador

RecyclerView necesita un adaptador para rellenar las vistas en cada fila (elemento horizontal) con sus datos. Crea un nuevo archivo java.

MyRecyclerViewAdapter.java

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {

    private List<Integer> mViewColors;
    private List<String> mAnimals;
    private LayoutInflater mInflater;
    private ItemClickListener mClickListener;

    // data is passed into the constructor
    MyRecyclerViewAdapter(Context context, List<Integer> colors, List<String> animals) {
        this.mInflater = LayoutInflater.from(context);
        this.mViewColors = colors;
        this.mAnimals = animals;
    }

    // inflates the row layout from xml when needed
    @Override
    @NonNull
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.recyclerview_item, parent, false);
        return new ViewHolder(view);
    }

    // binds the data to the view and textview in each row
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        int color = mViewColors.get(position);
        String animal = mAnimals.get(position);
        holder.myView.setBackgroundColor(color);
        holder.myTextView.setText(animal);
    }

    // total number of rows
    @Override
    public int getItemCount() {
        return mAnimals.size();
    }

    // stores and recycles views as they are scrolled off screen
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        View myView;
        TextView myTextView;

        ViewHolder(View itemView) {
            super(itemView);
            myView = itemView.findViewById(R.id.colorView);
            myTextView = itemView.findViewById(R.id.tvAnimalName);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
        }
    }

    // convenience method for getting data at click position
    public String getItem(int id) {
        return mAnimals.get(id);
    }

    // allows clicks events to be caught
    public void setClickListener(ItemClickListener itemClickListener) {
        this.mClickListener = itemClickListener;
    }

    // parent activity will implement this method to respond to click events
    public interface ItemClickListener {
        void onItemClick(View view, int position);
    }
}

Notas

  • Aunque no es estrictamente necesario, incluí la funcionalidad para escuchar eventos de clics en los elementos. Esto estaba disponible en el antiguo ListViews y es una necesidad común. Puede eliminar este código si no lo necesita.

Inicializar RecyclerView en actividad

Agregue el siguiente código a su actividad principal.

MainActivity.java

public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {

    private MyRecyclerViewAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // data to populate the RecyclerView with
        ArrayList<Integer> viewColors = new ArrayList<>();
        viewColors.add(Color.BLUE);
        viewColors.add(Color.YELLOW);
        viewColors.add(Color.MAGENTA);
        viewColors.add(Color.RED);
        viewColors.add(Color.BLACK);

        ArrayList<String> animalNames = new ArrayList<>();
        animalNames.add("Horse");
        animalNames.add("Cow");
        animalNames.add("Camel");
        animalNames.add("Sheep");
        animalNames.add("Goat");

        // set up the RecyclerView
        RecyclerView recyclerView = findViewById(R.id.rvAnimals);
        LinearLayoutManager horizontalLayoutManager
                = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false);
        recyclerView.setLayoutManager(horizontalLayoutManager);
        adapter = new MyRecyclerViewAdapter(this, viewColors, animalNames);
        adapter.setClickListener(this);
        recyclerView.setAdapter(adapter);
    }

    @Override
    public void onItemClick(View view, int position) {
        Toast.makeText(this, "You clicked " + adapter.getItem(position) + " on item position " + position, Toast.LENGTH_SHORT).show();
    }
}

Notas

  • Observe que la actividad implementa el ItemClickListener que definimos en nuestro adaptador. Esto nos permite manejar eventos de clic de elemento en onItemClick .

Terminado

Eso es. Debería poder ejecutar su proyecto ahora y obtener algo similar a la imagen en la parte superior.

Notas




Prueba esto:

myrecyclerview.setLayoutManager(
        new LinearLayoutManager(getActivity(),
                                LinearLayoutManager.HORIZONTAL,false));
myrecyclerview.setAdapter(recyclerAdapter);

solo en caso de que tengas una vista de reciclador con algunos fragmentos en ella.







Si desea utilizar la Vista del reciclador horizontal para actuar como ViewPager, ahora es posible con la ayuda de LinearSnapHelper que se agrega en la versión 24.2.0 de la Biblioteca de soporte.

En primer lugar, agregue RecyclerView a su actividad / fragmento

<android.support.v7.widget.RecyclerView
        android:layout_below="@+id/sign_in_button"
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:id="@+id/blog_list"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>

En mi caso he usado un CardView dentro del RecyclerView

blog_row.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 

    xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_margin="15dp"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical">

            <com.android.volley.toolbox.NetworkImageView
                android:id="@+id/imageBlogPost"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"
                android:paddingBottom="15dp"
                android:src="@drawable/common_google_signin_btn_text_light_normal" />

            <TextView
                android:id="@+id/TitleTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
               android:layout_marginBottom="20dp"

                android:text="Post Title Here"
                android:textSize="16sp" />

            <TextView
                android:id="@+id/descriptionTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Post Description Here"
                android:paddingBottom="15dp"
                android:textSize="14sp" />
        </LinearLayout>

    </android.support.v7.widget.CardView>

En tu Actividad / Fragmento

    private RecyclerView mBlogList;




 LinearLayoutManager layoutManager
                    = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
            mBlogList = (RecyclerView) findViewById(R.id.blog_list);

            mBlogList.setHasFixedSize(true);
            mBlogList.setLayoutManager(layoutManager);

LinearSnapHelper snapHelper = new LinearSnapHelper() {
            @Override
            public int findTargetSnapPosition(RecyclerView.LayoutManager lm, int velocityX, int velocityY) {
                View centerView = findSnapView(lm);
                if (centerView == null)
                    return RecyclerView.NO_POSITION;

                int position = lm.getPosition(centerView);
                int targetPosition = -1;
                if (lm.canScrollHorizontally()) {
                    if (velocityX < 0) {
                        targetPosition = position - 1;
                    } else {
                        targetPosition = position + 1;
                    }
                }

                if (lm.canScrollVertically()) {
                    if (velocityY < 0) {
                        targetPosition = position - 1;
                    } else {
                        targetPosition = position + 1;
                    }
                }

                final int firstItem = 0;
                final int lastItem = lm.getItemCount() - 1;
                targetPosition = Math.min(lastItem, Math.max(targetPosition, firstItem));
                return targetPosition;
            }
        };
        snapHelper.attachToRecyclerView(mBlogList);

El último paso es configurar el adaptador para RecyclerView

mBlogList.setAdapter(firebaseRecyclerAdapter);



 <android.support.v7.widget.RecyclerView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layoutManager="android.support.v7.widget.LinearLayoutManager" />



Si desea usar un RecyclerView con GridLayoutManager , esta es la manera de lograr un desplazamiento horizontal.

recyclerView.setLayoutManager(
new GridLayoutManager(recyclerView.getContext(), rows, GridLayoutManager.HORIZONTAL, false));



Tratar de construir un ListView horizontal está tomando demasiado tiempo. Lo he resuelto de dos maneras.

1. Mediante el uso de un ViewPager cuyo adaptador se extiende desde PagerAdapter.

2. Mediante el uso de RecyclerView tal como se indica arriba. Necesita aplicar LayoutManager como en el siguiente código:

LinearLayoutManager layoutManager
    = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);

RecyclerView myList = (RecyclerView) findViewById(R.id.my_recycler_view);
myList.setLayoutManager(layoutManager);



Bien, tan poco excavando y encontré estas gemas del article de Bill Philips sobre RecycleView

RecyclerView puede hacer más que ListView, pero la clase RecyclerView tiene menos responsabilidades que ListView. Fuera de la caja, RecyclerView no:

  • Posicionar elementos en la pantalla
  • Vistas animadas
  • Manejar cualquier evento táctil aparte del desplazamiento

Todo esto se incluyó en ListView, pero RecyclerView utiliza clases colaboradoras para realizar estos trabajos.

Los ViewHolders que creas son más sólidos también. Subclase RecyclerView.ViewHolder , que tiene varios métodos que usa RecyclerView . ViewHolders saben a qué posición están actualmente vinculados, así como también los ID de los ítems (si los tiene). En el proceso, ViewHolder ha sido nombrado caballero. Solía ​​ser el trabajo de ListView para conservar toda la vista de elementos, y ViewHolder solo se ViewHolder a pequeños fragmentos.

Ahora, ViewHolder se aferra a todo esto en el campo ViewHolder.itemView , que se asigna en el constructor de ViewHolder por usted.





android android-layout android-recyclerview