RecyclerView вызывает onBindViewHolder () для всех элементов [ScrollView не задействован] - PullRequest
0 голосов
/ 26 мая 2020

Я использую RecyclerView в приложении Android (API 23+) и обновляю его адаптер примерно до 380 элементов. Несмотря на то, что видны только 15 элементов, метод onBindViewHolder () адаптера RecyclerView вызывается для всех 380 элементов. Некоторые потоки описывают, что это происходит, когда RecyclerView находится внутри ScrollView или NestedScrollView; однако здесь дело обстоит иначе. Другое предложение - установить ширину представления ресайклера на 0dp или установить его высоту на wrap-content. Ни одна из подсказок в этом случае не работает.

Вот график c навигационного графика:

enter image description here

Вот код :

<?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 за пределами видимой области, пока пользователь не прокрутит.

1 Ответ

0 голосов
/ 28 мая 2020

Переход с RelativeLayout на FrameLayout исправляет это. Вот иерархия навигации после исправления.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...