RecyclerView 滚动使 findViewHolderForAdapterPosition 返回 null

Sar*_*ran 1 android nullpointerexception android-adapter android-recyclerview

我有一个RecyclerView水平的LinerLayout。它显示从 10 到 1 的数字,用于对某事物进行评分。

当我选择 10 并滚动回 1 并选择 1 时。我必须更新 UI 以删除 10 上的选择并更新 1 上的选择。但是,当我用来删除 10 上的选择时,findViewHolderForAdapterPosition()它给了我一个NullPointerException

我正在使用 ViewHolder 获取位置getAdapterPosition()

然后,我使用该位置通过调用我的回收器视图对象来获取 ViewHolder findViewHolderForAdapterPosition(),并更新 UI 以删除 10 中的选择。

vh = (RatingRecyclerAdapter.ViewHolder)
                mRecycler.findViewHolderForAdapterPosition(previousPosition);
vh.textRating.setBackgroundResource(R.drawable.rating_background_selected_orange);;
Run Code Online (Sandbox Code Playgroud)

通过一些测试,我发现当我尝试在不滚动的情况下做同样的事情时,效果很好。但是,只有当我滚动时,它才会给我一个NullPointerException

我该如何解决?

根据此处的要求,我们提供了 Adapter 类中的一些重要代码。

@Override
public void onBindViewHolder(RatingRecyclerAdapter.ViewHolder holder, int position) {
        String itemText = itemList.get(position);
        holder.textRating.setText(itemText);
}

public class ViewHolder extends RecyclerView.ViewHolder {

        TextView textRating;

        public ViewHolder(View itemView) {
            super(itemView);
            textRating = (TextView) itemView.findViewById(R.id.text_rating);
            textRating.setOnClickListener(ratingClickListener);
        }

        private final View.OnClickListener ratingClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = getAdapterPosition();
                if (callback != null) {
                    callback.onClickRating(v, position);
                }
            }
        };
    }
Run Code Online (Sandbox Code Playgroud)

活动课

@Override
public void onClickRating(View view, int position) {
        RatingRecyclerAdapter.ViewHolder vh;
        int color;

        int previousPosition = mAdapter.getSelectedPosition();  //Get previously clicked postion if any.
        if (previousPosition == Constants.NO_ITEM_SELECTED) {
            // An item was selected first time
            vh = (RatingRecyclerAdapter.ViewHolder)
                    mRecycler.findViewHolderForAdapterPosition(position);
            mAdapter.setSelectedPosition(position);  // Save new item selected position.
            color = Utility.getItemColor(mAdapter.getSelectedRating());
            mAdapter.setSelectedRatingResource(vh, color);
            return;
        }

        if (position == previousPosition) // Same item was selected
            return;

        vh = (RatingRecyclerAdapter.ViewHolder)
                mRecycler.findViewHolderForAdapterPosition(previousPosition);
        color = Utility.getItemColor(mAdapter.getSelectedRating());
        mAdapter.setUnselectedRatingResource(vh, color); // Remove the previous selected item drawables.

        vh = (RatingRecyclerAdapter.ViewHolder)
                mRecycler.findViewHolderForAdapterPosition(position);
        mAdapter.setSelectedPosition(position); // Save new item selected position.
        color = Utility.getItemColor(mAdapter.getSelectedRating());
        mAdapter.setSelectedRatingResource(vh, color); // Set the new selected item drawables. Setting some background to indicate selection.

    }
Run Code Online (Sandbox Code Playgroud)

Sar*_*ran 6

正如 Sevastyan 在评论中所写,RecyclerView一旦项目离开屏幕,就会立即回收视图。因此,如果我们调用findViewHolderForAdapterPosition()屏幕之外的视图,我们就会得到一个null值。(我不确定这是否是实际情况。但是,这就是我看来的情况。)

因此,我创建了一个类,该类存储有关某个项目的所有数据RecyclerView,并在该类中存储该项目的所有颜色和值。当我们填充视图时,根据该类中存储的数据设置所有颜色。

PS:我感谢 Sevastyan 没有直接给我答案。但是,只是给了我得到这个的理由Exception