简体   繁体   English

RecyclerView 将未选择的项目标记为已选择

[英]RecyclerView marks unselected items as selected

My RecyclerView repeats the marked item on Scrolling.我的 RecyclerView 在滚动上重复标记的项目。

My RecyclerView has 10 Lines which are actually displayed!我的 RecyclerView 有 10 行实际显示! If I click on the first, its background gets highlighted.如果我点击第一个,它的背景会突出显示。 If I scroll down now, another item is highlighted!如果我现在向下滚动,则会突出显示另一个项目!

If I scroll up, the first items isn't highlighted anymore, but another item...如果我向上滚动,第一个项目不再突出显示,而是另一个项目......

Here's an Image of the Problem:这是问题的图像:

Any my RecyclerViewAdapter:任何我的 RecyclerViewAdapter:

public class SelectSongRecyclerViewAdapter extends RecyclerView.Adapter<SelectSongRecyclerViewAdapter.Holder> {
    private Song[] sSongs;
    private List<Song> selectedSongs;

    public SelectSongRecyclerViewAdapter(Song[] songs) {
        sSongs = songs;

        selectedSongs = new ArrayList<>();
    }

    @Override
    public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_selectsongsview, parent, false);

        Holder holder = new Holder(view);

        return holder;
    }

    @Override
    public void onBindViewHolder(final Holder holder, final int position) {
        //holder.imvSong.setImageResource(R.drawable.standardartwork);
        holder.txvSongTitle.setText(sSongs[position].getTitle());
        holder.txvSongInfo.setText(sSongs[position].getArtists());

        holder.linearLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (selectedSongs.contains(sSongs[position])) {
                    selectedSongs.remove(sSongs[position]);
                    holder.linearLayout.setBackgroundResource(android.R.color.transparent);
                }
                else {
                    selectedSongs.add(sSongs[position]);
                    holder.linearLayout.setBackgroundResource(R.color.colorItemSelected);
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return sSongs != null ? sSongs.length : 0;
    }

    public Song[] getSelectedSongs() {
        Song[] songs = new Song[selectedSongs.size()];

        return selectedSongs.toArray(songs);
    }

    public class Holder extends RecyclerView.ViewHolder {
        LinearLayout linearLayout;
        ImageView imvSong;
        TextView txvSongTitle;
        TextView txvSongInfo;

        public Holder(View layout) {
            super(layout);

            linearLayout = (LinearLayout) layout;

            imvSong = (ImageView) layout.findViewById(R.id.imvSong);
            txvSongTitle = (TextView) layout.findViewById(R.id.adap_txvSongtitle);
            txvSongInfo = (TextView) layout.findViewById(R.id.adap_txvSongInfo);
        }
    }
}

I hope you can help me!我希望你能帮助我! Thanks!谢谢!

Here my working Code I used!这是我使用的工作代码!

When onBindViewHolder is called, the items are only selected if they are in the selectedSongs -List!当 onBindViewHolder 被调用时,只有在selectedSongs -List 中的项目才会被selectedSongs

@Override
public void onBindViewHolder(final Holder holder, int position) {
    holder.txvSongTitle.setText(sSongs[position].getTitle());
    holder.txvSongInfo.setText(sSongs[position].getArtists());

    if (!selectedSongs.contains(sSongs[position])) {
        holder.linearLayout.setBackgroundResource(android.R.color.transparent);
    }
    else {
        holder.linearLayout.setBackgroundResource(R.color.colorItemSelected);
    }

    holder.linearLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int pos = holder.getAdapterPosition();System.out.println(sSongs[pos].getTitle());

            if (selectedSongs.contains(sSongs[pos])) {
                selectedSongs.remove(sSongs[pos]);

                holder.linearLayout.setBackgroundResource(android.R.color.transparent);
            }
            else {
                selectedSongs.add(sSongs[pos]);

                holder.linearLayout.setBackgroundResource(R.color.colorItemSelected);
            }
        }
    });
}

This is how RecyclerView works: - creates as many Views can fit inside the screen and each time you scroll passes the view to onBindViewHolder in order to update it's data based on the item index这就是 RecyclerView 的工作原理: - 创建尽可能多的视图可以容纳在屏幕内,每次滚动时将视图传递给 onBindViewHolder 以便根据项目索引更新它的数据

Now when one of the views is clicked you change the background color of the view and when you scroll you pass a view with backgroundColor (colorItemSelected) and just change it's data.现在,当单击其中一个视图时,您会更改视图的背景颜色,当您滚动时,您会传递一个带有 backgroundColor (colorItemSelected) 的视图并更改它的数据。

What you should do is onBindViewHolder set view's background color to colorItemSelected if item is selected OR transparent if not.您应该做的是 onBindViewHolder 将视图的背景颜色设置为 colorItemSelected 如果项目被选中或透明如果没有。

Here is some co这是一些合作

 public void onBindViewHolder(final Holder holder, final int position) {
    //holder.imvSong.setImageResource(R.drawable.standardartwork);
    holder.txvSongTitle.setText(sSongs[position].getTitle());
    holder.txvSongInfo.setText(sSongs[position].getArtists());
    if (selectedSongs.contains(sSongs[position])) {  
              holder.linearLayout.setBackgroundResource(R.color.colorItemSelected);
    }else {
holder.linearLayout.setBackgroundResource(android.R.color.transparent);
}

    holder.linearLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (selectedSongs.contains(sSongs[position])) {
                selectedSongs.remove(sSongs[position]);
                holder.linearLayout.setBackgroundResource(android.R.color.transparent);
            }
            else {
                selectedSongs.add(sSongs[position]);
                holder.linearLayout.setBackgroundResource(R.color.colorItemSelected);
            }
        }
    });
}

try this adapter,试试这个适配器,

public class SelectSongRecyclerViewAdapter extends RecyclerView.Adapter<SelectSongRecyclerViewAdapter.Holder> { 
private Song[] sSongs;
private List<Song> selectedSongs;

public SelectSongRecyclerViewAdapter(Song[] songs) {
    sSongs = songs;

    selectedSongs = new ArrayList<>();
} 

@Override 
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_selectsongsview, parent, false);

    Holder holder = new Holder(view);

    return holder;
} 

@Override 
public void onBindViewHolder(final Holder holder, final int position) {
    holder.bind(position); 

} 

@Override 
public int getItemCount() { 
    return sSongs != null ? sSongs.length : 0;
} 

public Song[] getSelectedSongs() { 
    Song[] songs = new Song[selectedSongs.size()];

    return selectedSongs.toArray(songs);
} 

public class Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
    LinearLayout linearLayout;
    ImageView imvSong;
    TextView txvSongTitle;
    TextView txvSongInfo;

    public Holder(View layout) {
        super(layout);

        linearLayout = (LinearLayout) layout;

        imvSong = (ImageView) layout.findViewById(R.id.imvSong);
        txvSongTitle = (TextView) layout.findViewById(R.id.adap_txvSongtitle);
        txvSongInfo = (TextView) layout.findViewById(R.id.adap_txvSongInfo);
        linearLayout.setOnClickListener(this);
    }

    public void bind(int position){
        txvSongTitle.setText(sSongs[position].getTitle());
        txvSongInfo.setText(sSongs[position].getArtists());

        if (selectedSongs.contains(sSongs[getAdapterPosition()])) {
            linearLayout.setBackgroundResource(android.R.color.transparent);
        }
        else {
            linearLayout.setBackgroundResource(R.color.colorItemSelected);
        }
    }

    @Override
    public void onClick(View v) {
        if (selectedSongs.contains(sSongs[getAdapterPosition()])) {
            selectedSongs.remove(sSongs[getAdapterPosition()]);
            holder.linearLayout.setBackgroundResource(android.R.color.transparent);
        }
        else {
            selectedSongs.add(sSongs[getAdapterPosition()]);
            holder.linearLayout.setBackgroundResource(R.color.colorItemSelected);
        }
    }
}

} }

Change you onBindViewHolder to this将您的 onBindViewHolder 更改为此

    @Override
        public void onBindViewHolder(final Holder holder, final int position) {
            //holder.imvSong.setImageResource(R.drawable.standardartwork);
            holder.txvSongTitle.setText(sSongs[position].getTitle());
            holder.txvSongInfo.setText(sSongs[position].getArtists());

holder.linearLayout.setBackgroundResource(selectedSongs.contains(sSongs[position]) ? R.color.colorItemSelected : android.R.color.transparent);


            holder.linearLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (selectedSongs.contains(sSongs[position])) {
                        selectedSongs.remove(sSongs[position]);
                        notifyDataSetChanged();
                    }
                    else {
                        selectedSongs.add(sSongs[position]);
                        notifyDataSetChanged();
                    }
                }
            });
        }

Java爪哇

private int position = -1;

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
  holder.itemView.setSelected(holder.getLayoutPosition() == this.position);
  holder.itemView.setOnClickListener(v -> {
     holder.itemView.setSelected(true);
     this.position = holder.getLayoutPosition();
  });
}

Kotlin科特林

val position = -1

fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    holder.itemView.isSelected = holder.layoutPosition == this.position
    holder.itemView.setOnClickListener { v: View? ->
        holder.itemView.isSelected = true
        this.position = holder.layoutPosition
    }
}

item_background.xml item_background.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true">
        <shape>
            <solid android:color="@android:color/holo_blue_bright" />
        </shape>
    </item>

    <item>
        <shape>
            <solid android:color="@android:color/white" />
        </shape>
    </item>
</selector>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 删除recyclerView中的所有选定项目 - Deleting all selected items in recyclerView RecyclerView中的选定项目在滚动时发生更改 - Selected items in RecyclerView change on scrolling 更改 recyclerView Android (Java) 中选定项目的背景 - Changing the background of selected items in recyclerView Android (Java) Activity.java中的多个选定项目RecyclerView - Multiple selected items RecyclerView in Activity.java 如何在Android中的RecyclerView中跟踪所选项目? - How to keep track of the selected items in a RecyclerView in Android? 从 RecyclerView 中删除多个选定的项目 - Remove multiple selected items from a RecyclerView 如何在Android recyclerview中获取选中项{先前选择的数组项列表}设置为已选中{总计项} - How to get Selected items {list of previously selected array items} set as checked in android recyclerview {Total items} 在选定的水平 RecyclerView 项目上更新 ListView 项目数据 - Update ListView items data on horizontal RecyclerView item selected 关闭应用程序或切换片段时,将选定的项目保存在RecyclerView中 - Save selected items in RecyclerView when closing app or switching fragments JavaFX CheckBoxTreeItem检测复选框处于选中状态还是未选中状态 - JavaFX CheckBoxTreeItem detect when checkbox selected or unselected
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM