android - horizontal - recyclerview inside scrollview
RecyclerView dentro de NestedScrollView hace que RecyclerView infle todos los elementos (2)
Si tiene una gran cantidad de datos para mostrar, muestre solo algunos números de datos por primera vez que en desplazamiento utilice loadMoreListener para obtener los datos siguientes.
Tengo un problema al colocar un RecyclerView dentro de un NestedScrollView, que causa que se rendericen TODOS los elementos del adaptador RecyclerView.
Este es un problema bastante grande, ya que las listas que muestra RecyclerView pueden contener varios cientos de elementos.
En este momento está causando bastante retraso (obviamente), ya que tiene que representar todas las vistas a la vez, y no puede reutilizar las vistas ya infladas como lo hace normalmente RecyclerView.
Este es mi XML actual (eliminé algunos bloat para minimizarlo):
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="90dp">
<!-- Some content -->
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Some more content -->
</LinearLayout>
<!-- Product list -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"/>
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Este es mi onCreateView () del Fragmento que está inflando la vista que contiene el NestedScrollView y RecyclerView:
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.category_content_fragment, container, false);
ButterKnife.bind(this, root);
List<Product> products = new ArrayList<>(); //This is populated by other means, not relevant to the issue
productsRecyclerView.setNestedScrollingEnabled(false);
productsRecyclerView.setHasFixedSize(true);
productsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
ProductsContentAdapter productsContentAdapter = new ProductsContentAdapter(products);
productsRecyclerView.setAdapter(productsContentAdapter);
return root;
}
He visto esta publicación sobre el problema:
¿Cómo poner RecyclerView dentro de NestedScrollView?
Pero lamentablemente no menciona una solución final al problema.
Para aclarar: el RecyclerView se desplaza perfectamente, se muestra en el momento correcto, pero el problema es que representa TODOS sus hijos al instante, lo que significa que son posibles varios cientos de elementos, aunque la pantalla solo muestra 5-6 a la vez como máximo.
Por favor, siéntase libre de hacer preguntas si se necesita más información.
------- EDIT -------
Después de muchos intentos fallidos de otras soluciones, terminé usando la solución de Jeeva Nandhan.
Antes de hacer esta pregunta, sabía que era una posible solución, pero tenía 11 puntos de vista posibles diferentes que debían encajar en RecyclerView, por lo que me hubiera gustado evitarlo.
Después de usar diferentes ViewTypes, funcionó perfectamente. Temía que sería muy ineficiente debido a la gran cantidad de ViewTypes, pero es suave como la mantequilla.
Yo también me he encontrado con este problema ... Esto se debe a que tanto scrollview
como RecyclerView
son diferentes en la carga de datos, ya que ScrollView
actúa como el elemento principal en este caso y estamos utilizando la siguiente línea en nuestro código.
setNestedScrollingEnabled(false);
Esto hará que el desplazamiento sea lento y se bloquee según los datos de Recyclerview
.
Una manera que he usado para resolver este problema es agregar un encabezado a Recyclerview
.
Aquí lo explicaré claramente.
supongamos que esta recyclerview
está en nuestra actividad.
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
La clase de adaptador será así, donde agregaremos el encabezado
public class SampleAdapter extends RecyclerView.Adapter {
private final int BODY = 1;
private final int HEADER = 2;
private List<String> data = null;
SampleAdapter(List<String> data) {
this.data = data;
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
return HEADER;
}
return BODY;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case HEADER:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.inflate_header_layout, parent, false);
return new HeaderViewHolder(view);
default:
//Setting the Body view...
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.inflate_details, parent, false);
return new BodyViewHolder(view);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof BodyViewHolder) {
//Set the body content....
if (data != null && data.size() > 0) {
/** Since we have added one cell for header,
* we need to decrement the position and render the body view.
*
*/
int bodyPosition = position - 1;
}
} else if (holder instanceof HeaderViewHolder) {
//Set the header content...
}
}
@Override
public int getItemCount() {
//Sice we are going to add header, we are supposed increase the count by one...
return data.size() + 1;
}
}
por esto no hay necesidad de NestedScrollView
y toda la vista funcionará en el comportamiento de RecyclerView
...
Espero que esto sea útil :)