当前位置: 首页 > 知识库问答 >
问题:

为什么RecyclerView项目只在单击两次后更改背景色?

童华池
2023-03-14

我一直在探索回收站视图和Cardview,我偶然发现了一个问题,我不知道如何处理它。我的回收站视图工作正常,但是当我点击回收站视图的项目背景改变颜色时,它的行为很奇怪。

好的,回收器视图正常加载,但是当我第一次单击一个项目时,项目背景颜色会闪烁其新颜色,但会保持其默认颜色。当我第二次单击任何项目时,只有在回收器视图的项目更改其背景颜色时,它应该与单击的项目的其余部分一起更改。

从日志中。d我在代码中添加了,我发现第一次单击与第二次(以及其他)单击的不同之处在于公共的PremiseAdapter。类中的ViewHolder onCreateViewHolder(ViewGroup父级,int viewType)。我发现了一个与我的问题类似的问题,但我认为我的代码不是这样工作的。

日志如下。

  1. 加载recyclerview及其Cardview项目
.... D/rcvTest: PremiseAdapter.PremiseAdapter
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: ---------------------> PremiseAdapter.ViewHolder.onCreateViewHolder
.... D/rcvTest: [ViewHolder].ViewHolder.TOP
.... D/rcvTest: PremiseAdapter.onBindViewHolder
.... D/rcvTest: [ViewHolder].bindTo.TOP: FroyYo Mart
.... D/rcvTest: [ViewHolder].bindTo.BOTTOM FroyYo Mart
.... D/rcvTest: PremiseAdapter.onBindViewHolder.get(position)
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: ---------------------> PremiseAdapter.ViewHolder.onCreateViewHolder
.... D/rcvTest: [ViewHolder].ViewHolder.TOP
.... D/rcvTest: PremiseAdapter.onBindViewHolder
.... D/rcvTest: [ViewHolder].bindTo.TOP: Ice Cream Store
.... D/rcvTest: [ViewHolder].bindTo.BOTTOM Ice Cream Store
.... D/rcvTest: PremiseAdapter.onBindViewHolder.get(position)
.... D/rcvTest: [ViewHolder].ViewHolder.listener: null
.... D/rcvTest: [ViewHolder].ViewHolder.getAdapterPosition(): 1
.... D/rcvTest: [ViewHolder].ViewHolder.position: 1
.... D/rcvTest: getLayoutPosition(): 1
.... D/rcvTest: [ViewHolder].ViewHolder.position != RecyclerView.NO_POSITION
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: ---------------------> PremiseAdapter.ViewHolder.onCreateViewHolder
.... D/rcvTest: [ViewHolder].ViewHolder.TOP
.... D/rcvTest: PremiseAdapter.onBindViewHolder
.... D/rcvTest: [ViewHolder].bindTo.TOP: Ice Cream Store
.... D/rcvTest: [ViewHolder].bindTo.BOTTOM Ice Cream Store
.... D/rcvTest: PremiseAdapter.onBindViewHolder.get(position)
.... D/rcvTest: [ViewHolder].ViewHolder.listener: null
.... D/rcvTest: [ViewHolder].ViewHolder.getAdapterPosition(): 0
.... D/rcvTest: [ViewHolder].ViewHolder.position: 0
.... D/rcvTest: getLayoutPosition(): 0
.... D/rcvTest: [ViewHolder].ViewHolder.position != RecyclerView.NO_POSITION
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: PremiseAdapter.getItemCount
.... D/rcvTest: PremiseAdapter.onBindViewHolder
.... D/rcvTest: [ViewHolder].bindTo.TOP: FroyYo Mart
.... D/rcvTest: [ViewHolder].bindTo.BOTTOM FroyYo Mart
.... D/rcvTest: PremiseAdapter.onBindViewHolder.get(position)
.... D/rcvTest: PremiseAdapter.getItemCount

这是我的PremiseAdapter。java文件,其中包含我的PremiseAdapter类和ViewHolder类。

public class PremiseAdapter extends RecyclerView.Adapter<PremiseAdapter.ViewHolder> {

    private ArrayList<Premise> mPremiseData;
    private Context context;
    private int selected_position = -1;
    OnItemClickListener onItemClickListener;

    public interface OnItemClickListener {
        void onItemClick(int position);
    }

    public void setOnItemClickListener(OnItemClickListener itemClickListener) {
        onItemClickListener = itemClickListener;
    }

    public PremiseAdapter(Context context, ArrayList<Premise> mPremiseData) {
        Log.d("rcvTest", "PremiseAdapter.PremiseAdapter");
        this.mPremiseData = mPremiseData;
        this.context = context;
    }

    //Required method for creating the viewholder objects.
    @NonNull
    @Override
    public PremiseAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Log.d("rcvTest", "---------------------> PremiseAdapter.ViewHolder.onCreateViewHolder");
        return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.list_premises, parent, false), onItemClickListener);
    }

    //Required method that binds the data to the viewholder.
    @Override
    public void onBindViewHolder(@NonNull PremiseAdapter.ViewHolder holder, int position) {
        // Get current premise.

        // Populate the textviews with data.
    }

    @Override
    public int getItemCount() {
        Log.d("rcvTest", "PremiseAdapter.getItemCount");
        return mPremiseData.size();
    }


    /*----------------------------------- CLASS VIEWHOLDER -------------------------------------------*/
    /*----------------------------------- CLASS VIEWHOLDER -------------------------------------------*/

    /*class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {*/
    class ViewHolder extends RecyclerView.ViewHolder {
        // Member Variables for the TextViews

        //Constructor for the ViewHolder, used in onCreateViewHolder().
        ViewHolder(@NonNull View itemView, OnItemClickListener listener) {
            super(itemView);
            cardView = itemView.findViewById(R.id.cardview_premise);

            Log.d("rcvTest", "[ViewHolder].ViewHolder.TOP");
            // Initialize the views.

            // Set the OnClickListener to the entire view.
            int clickedColor = Color.parseColor("#D5F5E3");

            itemView.setOnClickListener((v) -> {
                int position = getAdapterPosition();
                Log.d("rcvTest", "[ViewHolder].ViewHolder.listener: " + listener);
                Log.d("rcvTest", "[ViewHolder].ViewHolder.getAdapterPosition(): " + getAdapterPosition());
                Log.d("rcvTest", "[ViewHolder].ViewHolder.position: " + position);
                Log.d("rcvTest", "getLayoutPosition(): " + getLayoutPosition());

                if (position != RecyclerView.NO_POSITION) {
                    Log.d("rcvTest", "[ViewHolder].ViewHolder.position != RecyclerView.NO_POSITION");
                    itemView.setBackgroundColor(clickedColor);
                } else if (position == RecyclerView.NO_POSITION) {
                    Log.d("rcvTest", "[ViewHolder].ViewHolder.position == RecyclerView.NO_POSITION");
                    itemView.setBackgroundColor(clickedColor);
                }
                notifyItemChanged(position);
                notifyItemChanged(getLayoutPosition());
            });
        }

        void bindTo(Premise currentPremise) {
            // Populate the textviews with data.
            Log.d("rcvTest", "[ViewHolder].bindTo.TOP: " + currentPremise.getPremiseName());
        }
    }
}

共有2个答案

万俟英锐
2023-03-14

试试这个。最近,我有这个代码,它的工作很好,希望这样也能解决你的问题。

 int row_index = -1;
 holder.itemView.setOnClickListener(v -> {
            row_index = position;
            notifyDataSetChanged();
        });
        if (row_index == position) {
            holder.layout.setBackgroundColor(Color.parseColor("#ff6600"));
        } else {
            holder.layout.setBackgroundColor(Color.parseColor("#ffffff"));
        }
白祺然
2023-03-14

我通常在onbindviewhold中实现onClick侦听器,它们似乎运行良好。我建议您应该尝试一下。
将这段代码移动到onbindviewhold

           int clickedColor = Color.parseColor("#D5F5E3");
            /*itemView.setBackgroundColor(defaultColor);*/

            holder.itemView.setOnClickListener((v) -> {
                int position = getAdapterPosition();
                Log.d("rcvTest", "[ViewHolder].ViewHolder.listener: " + listener);
                Log.d("rcvTest", "[ViewHolder].ViewHolder.getAdapterPosition(): " + getAdapterPosition());
                Log.d("rcvTest", "[ViewHolder].ViewHolder.position: " + position);
                Log.d("rcvTest", "getLayoutPosition(): " + getLayoutPosition());

                if (position != RecyclerView.NO_POSITION) {
                    Log.d("rcvTest", "[ViewHolder].ViewHolder.position != RecyclerView.NO_POSITION");
                    /*listener.onItemClick(position);*/
                    itemView.setBackgroundColor(clickedColor);
                } else if (position == RecyclerView.NO_POSITION) {
                    Log.d("rcvTest", "[ViewHolder].ViewHolder.position == RecyclerView.NO_POSITION");

                    itemView.setBackgroundColor(clickedColor);
                }
                notifyItemChanged(position);
                position = getLayoutPosition();
                notifyItemChanged(position); //duplicate
            });

只要确保改变

itemView.setOnClickListener(...)   to   holder.itemView.setOnClickListener(...)
 类似资料:
  • 我有一个清单,我在回收商的视图中展示了这一点 一些项目有蓝色背景和其他项目有灰色背景 我想编辑所选项目背景(所选项目表示已单击的项目) 这是我的适配器类

  • 在这里我有项目的列表在回收器视图这是取自Firebase.所以我试图改变其背景颜色当用户点击它.但是当我点击项目1然后项目4背景颜色也得到改变.如果点击项目2然后项目8颜色也.它给不恰当的结果。 视图持有者类

  • 问题内容: 我的问题是,如何解决以下问题: 如果我单击JTable中的单元格,我想更改其背景。如果我释放鼠标按钮,我希望背景变回正常颜色。 那可能吗? 问候ayk 问题答案: 在渲染器中,您必须覆盖 例如

  • 我想改变Long Press上Card View的背景,我访问了这么多论坛,但没有人给出正确的答案。 那么,如何改变列表/卡片/回收器视图的背景,就像长按导航视图项目一样??

  • 一个图像网格,当我点击包含图像的div时,选择的div应该改变背景。现在它只做了第二次,当检查页面源代码时,我可以看到添加了更改背景style=“background-color:rgb(xxx,xxx,xxx);”的代码。 CSS 脚本 HTML 选中时 选择其他时

  • 问题内容: 点击时可以更改背景颜色吗?全部,仅使用CSS和HTML5? 问题答案: 基于我在评论中发布的小提琴,我对它进行了少许修改,以使用Bootstrap按钮CSS。 只需包含Bootstrap的CSS文件,然后使用以下代码即可。 HTML CSS 这将使用相邻的兄弟选择器。 它在这里起作用:(我已经添加了防止选择标签文本的标签,但是标签不是必需的) 浏览器支持 Chrome,Firefox