滚动 Recycler View 时有意丢失数据

Posted

技术标签:

【中文标题】滚动 Recycler View 时有意丢失数据【英文标题】:Intent losing data when scrolling Recycler View 【发布时间】:2021-11-06 13:28:40 【问题描述】:

我正在尝试将一些文本从 Recycler View 发送到另一个 Activity,并且当屏幕没有滚动到底部时它可以正常工作。 但是当我向下滚动时,Intent 中的一些数据会丢失。当我向上滚动并单击按钮时,不会发生这种情况。

收藏按钮代码来自here.

我的适配器代码:

public class AdapterLanches extends RecyclerView.Adapter<AdapterLanches.MyViewHolder> implements Filterable 

public static MaterialFavoriteButton favoriteButton;
private List<Lanches> listaLanches;
private List<Lanches> listaLanchesCompleta;
public static Lanches itemAtual;
ArrayList<CharSequence> favoritos;
boolean fav = false;

int estadoPrograma;
public Button lc,fit;

int posicao = -1;

public class MyViewHolder extends RecyclerView.ViewHolder 

    public MaterialFavoriteButton favoriteButton;
    TextView titulo;
    RecyclerView recyclerView;


    public MyViewHolder(@NonNull View itemView) 
        super(itemView);
        lc = itemView.findViewById(R.id.lc);
        fit = itemView.findViewById(R.id.fit);
        favoriteButton = itemView.findViewById(R.id.favorite);

        favoriteButton.setOnFavoriteChangeListener(new MaterialFavoriteButton.OnFavoriteChangeListener() 
            @Override
            public void onFavoriteChanged(MaterialFavoriteButton buttonView, boolean favorite) 
               final int posicao = getAdapterPosition();
                fav = favorite;
                favoritos.add(listaLanchesCompleta.get(posicao).getTitulo());
                VeganoActivity.intentLanches2.putExtra("titulo", favoritos);
                System.out.println(favoritos);

            
        );

        titulo = itemView.findViewById(R.id.textnomeLanchesId);
        favoritos = new ArrayList<>();

    



public AdapterLanches(List<Lanches> listaLanches) 


    this.listaLanches = listaLanches;
    listaLanchesCompleta = new ArrayList<>(this.listaLanches);



@Override
public Filter getFilter() 
    return lanchesFilter;


public Filter lanchesFilter = new Filter() 
    @Override
    protected FilterResults performFiltering(CharSequence constraint) 
        List<Lanches> filteredList = new ArrayList<>();
        if (constraint == null || constraint.length() == 0)
            filteredList.addAll(listaLanchesCompleta);
        else
            estadoPrograma = 1;
            String filterPattern = constraint.toString().toLowerCase().trim();

            for ( Lanches item : listaLanchesCompleta)
                if (item.getTitulo().toLowerCase().contains(filterPattern))
                    filteredList.add(item);
                
            
        
        FilterResults results = new FilterResults();
        results.values = filteredList;
        results.count = filteredList.size();

        return results;
    

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) 
        listaLanches.clear();
        listaLanches.addAll((ArrayList<Lanches>)results.values);
        notifyDataSetChanged();
    
;


@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
    View itemListaLanches = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_lanches, parent, false);
    final MyViewHolder holder = new MyViewHolder(itemListaLanches);




    return holder;


@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) 

    itemAtual = listaLanches.get(position);
    holder.titulo.setText(itemAtual.getTitulo());


    if (itemAtual.getId() == 0)
        fit.setVisibility(View.GONE);
        lc.setVisibility(View.GONE);
    

    if (itemAtual.getId() == 1)
        lc.setVisibility(View.VISIBLE);
        fit.setVisibility(View.GONE);
    

    if (itemAtual.getId() == 2)
        fit.setVisibility(View.VISIBLE);
        lc.setVisibility(View.GONE);
    





@Override
public int getItemViewType(int position) 
    return position;


@Override
public int getItemCount() 

    return listaLanches.size();

欢迎任何帮助,谢谢。

【问题讨论】:

【参考方案1】:

创建一个列表,为这些数据提供更广泛的范围。因为 RecyclerView 会在它们消失时擦除它们。

var stuffINeedToKeep=mutableListOf<String>()//this goes right under the class constructor so that it has wide scope
...
heart.setOnClickListener(
stuffINeedToKeep.add(dataFromViewHolder)
)

【讨论】:

ArrayList 收藏;和 favouritos.add(listaLanchesCompleta.get(posicao).getTitulo());不是已经这样做了吗? 我不知道这是否是导致问题的原因,但我认为在每个 onCreateViewHolder 上重新实例化收藏夹是个坏主意 但它在 MyViewHolder 构造函数中,而不是 OnBindViewHolder 你认为我可以把它放在更好的地方吗? 我看到了,但它是从 onCreateViewHolder 调用的,并且您无法很好地控制何时发送。以下 recyclerview 工作流程我从来没有遇到过任何问题。我定义了数据集,它将完全在 recyclerview 之外控制适配器,赋予它活动级别的范围。然后我在 oncreate 期间填充它。如果我从服务器获取内容,我将使用分页查询填充它并从 oncreate 进行第一次调用。然后我将该数据集传递给适配器的构造函数。易于阅读和更改数据集并在更改时调用 notify()。

以上是关于滚动 Recycler View 时有意丢失数据的主要内容,如果未能解决你的问题,请参考以下文章

当用户将手从屏幕上移开时,如何使 Recycler View 滚动缓慢而流畅?

如何在 kotlin 的 Recycler View Adapter 中添加更多数据列表而不清除先前的数据?

如何使 Recycler View 表现得像 PlayStore Recycler Views

如何制作自定义形状的 Recycler View?

如何将我的 Recycler View 设计为与 Chanel App 的设计相似?

Recycler View 不显示数据