RecycleView突出显示错误的行(Android)

时间:2016-06-21 19:23:12

标签: android

我正在尝试突出显示列表,例如当用户点击某行时,其背景会改变颜色。该应用程序工作正常,但当我在列表中上下滚动时,突出显示一行,突然其他行也突出显示。 以下是显示此行为的测试应用程序(代码基于http://inducesmile.com/android/how-to-set-recycleview-item-row-background-color-in-android/)。

主要活动

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
    LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
    recyclerView.setLayoutManager(layoutManager);

    List<ItemObject> posts = returnListItems();

    RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainActivity.this, posts);
    recyclerView.setAdapter(adapter);
}

private List<ItemObject> returnListItems(){
    List<ItemObject> items = new ArrayList<ItemObject>();
    items.add(new ItemObject("Blank Space", "Taylor Swift", "2016"));
    items.add(new ItemObject("Uptown Funk", "Mark Ronson", "2016"));
    items.add(new ItemObject("Can't Feel My Face", "The Weeknd", "2016"));
    items.add(new ItemObject("Cheerleader", "OMI", "2016"));
    items.add(new ItemObject("What Do You Mean?", "Justin Bieber", "2016"));
    items.add(new ItemObject("Hello", "Adele", "2016"));
    items.add(new ItemObject("Blank Space", "Taylor Swift", "2016"));
    items.add(new ItemObject("Uptown Funk", "Mark Ronson", "2016"));
    items.add(new ItemObject("Can't Feel My Face", "The Weeknd", "2016"));
    items.add(new ItemObject("Cheerleader", "OMI", "2016"));
    items.add(new ItemObject("What Do You Mean?", "Justin Bieber", "2016"));
    items.add(new ItemObject("Hello", "Adele", "2016"));
    items.add(new ItemObject("Blank Space", "Taylor Swift", "2016"));
    items.add(new ItemObject("Uptown Funk", "Mark Ronson", "2016"));
    items.add(new ItemObject("Can't Feel My Face", "The Weeknd", "2016"));
    items.add(new ItemObject("Cheerleader", "OMI", "2016"));
    items.add(new ItemObject("What Do You Mean?", "Justin Bieber", "2016"));
    items.add(new ItemObject("Hello", "Adele", "2016"));
    items.add(new ItemObject("Blank Space", "Taylor Swift", "2016"));
    items.add(new ItemObject("Uptown Funk", "Mark Ronson", "2016"));
    items.add(new ItemObject("Can't Feel My Face", "The Weeknd", "2016"));
    items.add(new ItemObject("Cheerleader", "OMI", "2016"));
    items.add(new ItemObject("What Do You Mean?", "Justin Bieber", "2016"));
    items.add(new ItemObject("Hello", "Adele", "2016"));
    items.add(new ItemObject("Blank Space", "Taylor Swift", "2016"));
    items.add(new ItemObject("Uptown Funk", "Mark Ronson", "2016"));
    items.add(new ItemObject("Can't Feel My Face", "The Weeknd", "2016"));
    items.add(new ItemObject("Cheerleader", "OMI", "2016"));
    items.add(new ItemObject("What Do You Mean?", "Justin Bieber", "2016"));
    items.add(new ItemObject("Hello", "Adele", "2016"));
    return items;
}

RecyclerViewHolders

public class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{

public TextView songTitle;
public TextView songYear;
public TextView songAuthor;

private static int selectedPos = -1;
private static View selectedView = null;

public RecyclerViewHolders(View itemView) {
    super(itemView);
    itemView.setOnClickListener(this);
    songTitle = (TextView)itemView.findViewById(R.id.song_title);
    songYear = (TextView)itemView.findViewById(R.id.song_year);
    songAuthor = (TextView)itemView.findViewById(R.id.song_author);
}

@Override
public void onClick(View view) {
    int position = getAdapterPosition();
    if (selectedPos == position){       // deselect the row
        selectedView.setSelected(false);
        selectedPos = -1;   // no selected row
    }else {
        if (selectedPos != -1)
            selectedView.setSelected(false);           // deselect the row
        selectedView = view;
        selectedPos = position;
        selectedView.setSelected(true);
    }
}
}

RecyclerViewAdapter

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders>{

private List<ItemObject> itemList;

public RecyclerViewAdapter(Context context, List<ItemObject> itemList) {
    this.itemList = itemList;
}

@Override
public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
    View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null);
    return new RecyclerViewHolders(layoutView);
}

@Override
public void onBindViewHolder(RecyclerViewHolders holder, int position) {
    holder.songTitle.setText("" + position + "   Song Title: " + itemList.get(position).getSongTitle());
    holder.songYear.setText("Song Year: " + itemList.get(position).getSongYear());
    holder.songAuthor.setText("Song Author: " + itemList.get(position).getSongAuthor());
}

@Override
public int getItemCount() {
    return this.itemList.size();
}
}

ItemObject

public class ItemObject {

private String songTitle;
private String songYear;
private String songAuthor;

public ItemObject(String songTitle, String songYear, String songAuthor) {
    this.songTitle = songTitle;
    this.songYear = songYear;
    this.songAuthor = songAuthor;
}

public String getSongTitle() {
    return songTitle;
}

public String getSongYear() {
    return songYear;
}

public String getSongAuthor() {
    return songAuthor;
}
}

1 个答案:

答案 0 :(得分:1)

这是因为在Recycler View中,视图会被回收。这意味着再次使用相同的视图来显示其他项目。因此,一旦另一个视图开始使用已选择的相同视图,它就会开始显示不正确的结果。

要纠正此问题,您必须在onBindViewHolder代码中进行修改。如下所示:

 @Override
    public void onBindViewHolder(RecyclerViewHolders holder, int position) {
       View view = holder.getView(); //Please check the appropriate function which returns the "itemView" from view holder.
       if(position == holder.getSelectedPosition()) //Add a getter method for selected position
       {
          view.setSelected(true);
       }
       else {
          view.setSelected(false);
        }

        holder.songTitle.setText("" + position + "   Song Title: " + itemList.get(position).getSongTitle());
        holder.songYear.setText("Song Year: " + itemList.get(position).getSongYear());
        holder.songAuthor.setText("Song Author: " + itemList.get(position).getSongAuthor());
    }