我爲列表視圖使用自定義列表適配器。我在列表視圖中定義了一個按鈕,點擊事件起作用,但問題是一旦列表滾動,它就會用同一個按鈕綁定多個視圖。因此,點擊按鈕時,與每個關聯視圖關聯的事件被觸發。按鈕點擊綁定到自定義列表視圖中的多個視圖
我該如何處理?
我爲列表視圖使用自定義列表適配器。我在列表視圖中定義了一個按鈕,點擊事件起作用,但問題是一旦列表滾動,它就會用同一個按鈕綁定多個視圖。因此,點擊按鈕時,與每個關聯視圖關聯的事件被觸發。按鈕點擊綁定到自定義列表視圖中的多個視圖
我該如何處理?
我想你會誤解這個列表是如何工作的 - 尤其是如何使用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;
}
那反正是我的猜測:)
斯圖爾特是完全正確的 - 問題是,意見中的ListView重複使用(以避免產生不同的對象),和列表的不同部分是可見的,因爲你的新位置可以得到任何不再使用的視圖。所以你的代碼應該正確處理。 我想補充一點,monodroid中的Java對象的垃圾收集效果不好。根據我的經驗,創建大量來自Java.Lang.Object的對象會使應用程序崩潰。所以:
爲每個新行創建新的視圖很快會使應用程序崩潰,因此您必須儘可能重用convertView。
標籤有類型Java.Lang.Object,所以WrappedPosition應該從Java對象派生。這意味着,不是每次都創建新的實例,而應該重用相同的實例。
如果您將點擊處理程序移動到單獨的方法,您可以在訂閱之前取消訂閱,因此您不需要任何邏輯「如果視圖爲空」。
如果您覺得它有用,我可以在這裏發佈解釋它如何工作的代碼示例。 Dodn't最初發布它,因爲它是相當大的:)
顯示您的代碼。沒有代碼它不可能解決:) –
view =(convertView ?? context.LayoutInflater.Inflate(Resource.Layout.HotelCustomListItem,parent,false))作爲LinearLayout; –
這基本上是在這裏完成的。我在上述佈局中定義了一個按鈕。當列表滾動時,會創建新視圖,但與每個視圖關聯的控件似乎是相同的。 –