2012-11-08 160 views
0

我爲列表視圖使用自定義列表適配器。我在列表視圖中定義了一個按鈕,點擊事件起作用,但問題是一旦列表滾動,它就會用同一個按鈕綁定多個視圖。因此,點擊按鈕時,與每個關聯視圖關聯的事件被觸發。按鈕點擊綁定到自定義列表視圖中的多個視圖

我該如何處理?

+1

顯示您的代碼。沒有代碼它不可能解決:) –

+0

view =(convertView ?? context.LayoutInflater.Inflate(Resource.Layout.HotelCustomListItem,parent,false))作爲LinearLayout; –

+0

這基本上是在這裏完成的。我在上述佈局中定義了一個按鈕。當列表滾動時,會創建新視圖,但與每個視圖關聯的控件似乎是相同的。 –

回答

0

我想你會誤解這個列表是如何工作的 - 尤其是如何使用convertView。

列表視圖中的Android虛擬化的用戶界面 - 就像列表框做WP和就像UITableViews做的iOS

這意味着,如果底層的列表中有1000個項目,但屏幕只有房間10個項目,那麼列表只會創建10個「容器」來顯示列表項目,並將使用這些容器來顯示當時正在查看的內容。

它這樣做的方式是通過適配器 - 特別是通過GetView回調 - 它將convertView作爲其參數之一。

如果您選擇在GetView實現來創建一個新的觀點,那麼你可以訂閱回調的新事件...

相反,如果你選擇使用convertView在GetView實現,那麼你應該不要在回調中訂閱新事件 - 不要先退訂舊事件。

例如我猜你的代碼確實是這樣的僞目前:

public View GetView(int pos, View convertView) 
{ 
    TextView toShow = convertView as TextView; 
    if (toShow == null) 
    { 
     toShow = new TextView(); 
    } 

    toShow.Text = "Item at position " + i; 
    toShow.Click += (s,e) => { 
     // do something 
    }; 

    return toShow; 
} 

與代碼的問題是,你將認購過於頻繁點擊......你需要的東西,如來解決它:

public View GetView(int pos, View convertView) 
{ 
    TextView toShow = convertView as TextView; 
    if (toShow == null) 
    { 
     toShow = new TextView(); 
     toShow.Click += (s,e) => { 
      // do something with the position embedded in toShow.Tag 
     }; 
    } 

    toShow.Text = "Item at position " + i; 
    toShow.Tag = new WrappedPosition(i); 
    return toShow; 
} 

那反正是我的猜測:)

0

斯圖爾特是完全正確的 - 問題是,意見中的ListView重複使用(以避免產生不同的對象),和列表的不同部分是可見的,因爲你的新位置可以得到任何不再使用的視圖。所以你的代碼應該正確處理。 我想補充一點,monodroid中的Java對象的垃圾收集效果不好。根據我的經驗,創建大量來自Java.Lang.Object的對象會使應用程序崩潰。所以:

  1. 爲每個新行創建新的視圖很快會使應用程序崩潰,因此您必須儘可能重用convertView。

  2. 標籤有類型Java.Lang.Object,所以WrappedPosition應該從Java對象派生。這意味着,不是每次都創建新的實例,而應該重用相同的實例。

  3. 如果您將點擊處理程序移動到單獨的方法,您可以在訂閱之前取消訂閱,因此您不需要任何邏輯「如果視圖爲空」。

如果您覺得它有用,我可以在這裏發佈解釋它如何工作的代碼示例。 Dodn't最初發布它,因爲它是相當大的:)

相關問題