2014-10-27 30 views
1

我跟着這裏這個例子:https://developer.android.com/training/material/lists-cards.html無法獲得RecyclerView.Adapter才能正確顯示

發生了什麼

名單(RecyclerView)被混合起來的數據,當我滾動。即當我向下滾動後向後滾動時,某些列表項會重複出現,而不會顯示正確的內容。

這裏是我的onBindViewHolder方法:

// cardsData is a List of MyCardItem (MyCardItem is just a holder of information, 
// such as an id, String title, String summary, and other info to display on a card 
@Override 
public void onBindViewHolder(ViewHolder viewHolder, int position) 
{ 
    // Update view here 
    if (!cardsData.isEmpty()) 
    { 
     viewHolder.updateDisplay(cardsData.get(position), activity, position); 
    } 
} 

這裏是ViewHolder類中找到了我的updateDisplay方法:

// Set ID 
if (item.getID() != null) 
{ 
    mIDView.setText(item.getID()); 
} 

// Set Title 
if (item.getTitle() != null) 
{ 
    mTitleView.setText(item.getTitle()); 
} 

// Set Summary 
if (item.getSummary() != null) 
{ 
    mSummaryView.setText(Html.fromHtml(item.getSummary())); 
} 

// Image 
if (item.hasImage()) 
{ 
    // Display image here 
} 

我相信它有東西做的事實,有時數據爲空,所以我選擇不顯示它。並非所有項目(卡片)都會顯示圖像,所以這就是我檢查項目是否應該有圖像的原因。如果是這樣,那麼我會做一些奇特的代碼來顯示圖像(並使其他視圖GONE因此我只能顯示該圖像等)。

在調試過程中,我強制所有卡在標題中顯示其標識和位置。我可以確認所有ID和職位都是。當我強制(刪除if,檢查id,title和summary)顯示id,title和summary時,即使爲null,該內容也不會受到影響。但是,這並不能解決我的圖像情況(不會總是有圖像)。然後我會有一些圖像佔據某個特定位置的位置,它應該是而不是(即不是顯示摘要文本,而是顯示不應該在那裏的圖像)。

爲什麼在我的RecyclerView中發生這種情況的任何輸入?

回答

12

RecyclerView,與ListViewGridView一樣,只要有可能就重新使用視圖。這意味着當您滾動時,視圖會從底部開始用於底部的視圖等,這將大大提高內存效率和滾動性能。這意味着如果您沒有在新項目上重置全部狀態,則會看到上次使用此視圖時遺留的狀態。

相反,你應該始終重置所有的狀態:

if (item.getID() != null) { 
    mIDView.setText(item.getID()); 
} else { 
    mIDView.setText(""); 
} 
// etc... 

而且,不應該有,你需要檢查cardsData.isEmpty()任何情況下 - 相反,當你更新cardsData,你應該調用適當的notifyXXX方法(如notifyItemInserted()或更糟糕的情況下notifyDataSetChanged())將自動適當地刷新列表。

+1

謝謝!同時感謝_notify_上的領導。 – user1234 2014-10-27 18:48:55

+0

很好的解釋,但是如果你正在做這件事,並且回收者視圖保留了錯誤的觀點和數據收集,你會怎麼做? (重複每個項目的值) – 2016-03-17 19:44:58

1

而且除了前面的回答,您可以在空虛檢查視圖,例如:

if (TextUtils.isEmpty(viewHolder.item.getText())) { 
     viewHolder.item.setText(object.getItem()); 
    } 
4

以其它方式實現

public long getItemId(int position) {} 

,你會看到在RecyclerView重複項目。

+4

你能解釋更多嗎? – divyenduz 2015-07-22 15:36:59

0

詳細闡述ViliusK的答案。此實現將工作:

@Override 
public long getItemId(int position) { 
    Object obj = getItemAtPosition(position); 
    return obj.hashCode(); 
} 
3

加入這兩個,你是好去!

@Override 
public long getItemId(int position) { 
    return position; 
} 

@Override 
public int getItemViewType(int position) { 
    return position; 
} 
+0

這救了我的命 – busuu 2017-03-20 01:26:19