2016-06-21 7 views
1

Ich versuche, eine Liste zu erstellen, wenn der Benutzer beispielsweise auf eine Zeile klickt, deren Hintergrund die Farbe ändert. Die App funktioniert gut, aber wenn ich in der Liste nach oben und unten scrolle, während eine Zeile markiert ist, werden plötzlich auch andere Zeilen hervorgehoben. Das folgende ist eine Test-App, die dieses Verhalten zeigt (Code basiert auf http://inducesmile.com/android/how-to-set-recycleview-item-row-background-color-in-android/).RecycleView hebt die falsche Zeile hervor (Android)

Hauptaktivität

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; 
} 
} 
+0

Haben Sie den vollständigen Code von 'RecyclerViewHolders' gepostet? Ich sehe nicht, wie 'selectedView' initialisiert wird. – jaibatrik

+0

Es wird in onClick() initialisiert, sobald eine Zeile ausgewählt ist (zunächst ist es auf Null gesetzt) ​​- siehe die Zeile 'selectedView = view' – Zvi

Antwort

1

Dies liegt daran, in Recycler Ansicht der Ansicht recycelt wird. Das bedeutet, dass dieselbe Ansicht erneut zum Anzeigen anderer Elemente verwendet wird. Sobald die andere Ansicht beginnt, dieselbe Ansicht zu verwenden, die ausgewählt wurde, werden falsche Ergebnisse angezeigt.

Um dies zu korrigieren, müssen Sie Änderungen an Ihrem onBindViewHolder-Code vornehmen. Etwas wie unten:

@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()); 
    } 
+0

Danke @Aprit Ratan. Es funktionierte. Die fehlende "Funktion" ist View view = holder.itemView; – Zvi

+0

Ich bin froh, dass es geholfen hat :) –

Verwandte Themen