【发布时间】:2020-05-26 20:55:10
【问题描述】:
我在一个 Android 应用(API 23+)中使用了 RecyclerView,并用大约 380 个项目更新了它的适配器。即使只有 15 个项目可见,RecyclerView 的适配器的 onBindViewHolder() 方法也会为所有 380 个项目调用。一些线程描述当 RecyclerView 在 ScrollView 或 NestedScrollView 内时会发生这种情况;但是,这里不是这样。另一个建议是将回收器视图的宽度设置为 0dp 或将其高度设置为 wrap-content。在这种情况下,两个提示都不起作用。
这是导航图的图形:
代码如下:
<?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();
}
}
行为如下:当有更新时,使用新的 BoxInside 对象列表调用适配器的 update() 方法。我希望 RecyclerView 明显清除、更新它的数据集并更新视图,但不要担心在用户滚动之前在可见区域之外创建 ViewHolders。
【问题讨论】:
-
让我们看看你的适配器代码
标签: android android-recyclerview