Я использую RecyclerView в приложении Android (API 23+) и обновляю его адаптер примерно до 380 элементов. Несмотря на то, что видны только 15 элементов, метод onBindViewHolder () адаптера RecyclerView вызывается для всех 380 элементов. Некоторые потоки описывают, что это происходит, когда RecyclerView находится внутри ScrollView или NestedScrollView; однако здесь дело обстоит иначе. Другое предложение - установить ширину представления ресайклера на 0dp или установить его высоту на wrap-content. Ни одна из подсказок в этом случае не работает.
Вот график c навигационного графика:
![enter image description here](https://i.stack.imgur.com/efFon.png)
Вот код :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- TABLE TITLE-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/mid_gray"
android:gravity="top"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<TextView
android:id="@+id/txt_table_title_0"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_weight="0.7"
android:text="@string/caja"
android:textStyle="bold" />
<TextView
android:id="@+id/txt_table_title_variedad"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/variedad"
android:textStyle="bold" />
<TextView
android:id="@+id/txt_table_title_date"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/ingreso"
android:textStyle="bold" />
<TextView
android:id="@+id/txt_table_title_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".7"
android:text="@string/semanas"
android:textStyle="bold" />
<TextView
android:id="@+id/txt_table_title_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cantidad"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".7" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Вот код адаптера
package com.plantecuador.poscosecha.adapter;
import android.annotation.SuppressLint;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.plantecuador.poscosecha.R;
import com.plantecuador.poscosecha.db.entities.BoxInside;
import com.plantecuador.poscosecha.event.BoxInsideSelectedEvent;
import com.plantecuador.poscosecha.helper.DateFormatHelper;
import com.plantecuador.poscosecha.viewholder.ThrowOutViewHolder;
import org.greenrobot.eventbus.EventBus;
import org.threeten.bp.DateTimeUtils;
import org.threeten.bp.Instant;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.ZoneId;
import org.threeten.bp.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import timber.log.Timber;
public class ThrowOutAdapter extends RecyclerView.Adapter<ThrowOutViewHolder> {
private ArrayList<BoxInside> insides = new ArrayList<>();
@NonNull
@Override
public ThrowOutViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_throw_out, parent, false);
return new ThrowOutViewHolder(view);
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull ThrowOutViewHolder vh, int position) {
Timber.v("onBindViewHolder called in throwout and position %s", position);
if (position % 2 == 0) {
vh.rowLayout.setBackgroundColor(Color.WHITE);
} else {
vh.rowLayout.setBackgroundColor(Color.parseColor("#D8D8D8"));
}
BoxInside inside = insides.get(position);
vh.txtInsideNumber.setText(inside.getId());
Date date = (inside.getDateCFOrigPacked() == null) ? inside.getDatePacked() : inside.getDateCFOrigPacked();
String strDate = DateFormatHelper.formatToDateString("dd/MM/yy", date);
vh.txtDate.setText(strDate);
vh.txtQuantity.setText(inside.getQuantity() + "");
vh.txtVariety.setText(inside.getVariety() + "");
Instant instantStart = DateTimeUtils.toInstant(date);
LocalDateTime localStart = LocalDateTime.ofInstant(instantStart, ZoneId.systemDefault());
Instant instantEnd = DateTimeUtils.toInstant(new Date());
LocalDateTime localEnd = LocalDateTime.ofInstant(instantEnd, ZoneId.systemDefault());
long weeks = ChronoUnit.WEEKS.between(localStart, localEnd);
vh.txtAge.setText(weeks + "");
assert vh.btnVer != null;
vh.btnVer.setOnClickListener(view -> EventBus.getDefault().post(new BoxInsideSelectedEvent(inside)));
}
@Override
public int getItemCount() {
return insides.size();
}
public void update(List<BoxInside> insides) {
this.insides.clear();
this.insides.addAll(insides);
Timber.v("About to notify dataset changed");
notifyDataSetChanged();
}
}
Поведение следующее: метод update () адаптера вызывается с новым списком объектов BoxInside, когда есть обновления. Я бы хотел, чтобы RecyclerView явно очищал, обновлял свой набор данных и обновлял представление, но не беспокоился о создании ViewHolders за пределами видимой области, пока пользователь не прокрутит.