¿Cómo construir un ListView horizontal con RecyclerView?

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

¿Hay una mejor manera de implementar esto ahora con Recyclerview ahora?

Sí.

Cuando utiliza un RecyclerView , necesita especificar un LayoutManager que es responsable de diseñar cada elemento en la vista. El LinearLayoutManager permite especificar una orientación, como LinearLayout haría un LinearLayout normal.

Para crear una lista horizontal con RecyclerView , puede hacer algo como esto:

 LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false); RecyclerView myList = (RecyclerView) findViewById(R.id.my_recycler_view); myList.setLayoutManager(layoutManager); 
   

Ejemplo completo

enter image description here

La única diferencia real entre un RecyclerView vertical y uno horizontal es cómo configura el 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 vertical RecyclerView .

Actualizar las 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 RecyclerView a su diseño xml.

activity_main.xml

     

Crear diseño del elemento

Cada elemento en nuestro RecyclerView va a tener una única View coloreada sobre un TextView . Crea un nuevo archivo de recursos de diseño.

recyclerview_item.xml

      

Crea el adaptador

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

MyRecyclerViewAdapter.java

 public class MyRecyclerViewAdapter extends RecyclerView.Adapter { private List mViewColors; private List mAnimals; private LayoutInflater mInflater; private ItemClickListener mClickListener; // data is passed into the constructor MyRecyclerViewAdapter(Context context, List colors, List 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 ítems. Esto estaba disponible en las antiguas ListViews y es una necesidad común. Puede eliminar este código si no lo necesita.

Inicializar RecyclerView en la 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 viewColors = new ArrayList<>(); viewColors.add(Color.BLUE); viewColors.add(Color.YELLOW); viewColors.add(Color.MAGENTA); viewColors.add(Color.RED); viewColors.add(Color.BLACK); ArrayList 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 horizontalLayoutManagaer = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false); recyclerView.setLayoutManager(horizontalLayoutManagaer); 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 elementos en onItemClick .

Terminado

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

Notas

  • Las vistas en color de mi ejemplo podrían, por supuesto, ser reemplazadas por imágenes en un proyecto real.
  • Ejemplo vertical RecyclerView

Si desea utilizar un RecyclerView con el GridLayoutManager , esta es la forma de lograr 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. Al usar un ViewPager cuyo adaptador se extiende desde PagerAdapter.

2. Al usar RecyclerView 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); 

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

Primero, agregue RecyclerView a su actividad / fragmento

   

En mi caso, he usado un CardView dentro de RecyclerView

blog_row.xml

         

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 a RecyclerView

 mBlogList.setAdapter(firebaseRecyclerAdapter); 

Con el lanzamiento de la biblioteca RecyclerView, ahora puede alinear fácilmente una lista de imágenes vinculadas con texto. 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.

enter image description here

Puede descargar una demostración completa de esta publicación

Existe una subclase RecyclerView llamada HorizontalGridView que puede usar para tener una dirección horizontal. VerticalGridView para dirección vertical

Prueba esto:

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

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