2012-11-14 205 views
3

我已經實現了一個自定義BaseAdapter,它顯示具有自定義佈局的列表項目。刪除列表視圖項目從列表視圖項目按鈕

一切正常,但我試圖添加一個刪除按鈕出現在項目旁邊(我有),但我有問題試圖讓它工作。

相關的代碼是在這裏:

public List<OrderLineItem> Items 
    { 
     get; 
     set; 
    } 

    public override View GetView(int position, View convertView, ViewGroup parent) 
    { 
     OrderLineItem item = GetItemAtPosition(position); 

     var view = (convertView ?? 
      Context.LayoutInflater.Inflate(Resource.Layout.CustomListItem, parent, false)) as LinearLayout; 

     // .......... 
     var removeButton = view.FindViewById(Resource.Id.btnRemove) as Button; 

     removeButton.Click += delegate 
     { 
      Items.RemoveAt(position); 
      this.NotifyDataSetChanged(); 
     }; 

     // ........... 

     return view; 
    } 

的問題是,我認爲,由於委託關閉,因爲Items.Count總是等於的位置偏移。

回答

2

我認爲你對導致問題的閉包的分析可能是正確的。

爲了解決這個問題,我會考慮在視圖上使用標記字段來存儲當前項目 - 然後在刪除操作中使用它。

public override View GetView(int position, View convertView, ViewGroup parent) 
{ 
    OrderLineItem item = GetItemAtPosition(position); 

    var view = convertView; 

    if (view == null) 
    { 
     view = Context.LayoutInflater.Inflate(Resource.Layout.CustomListItem, parent, false)) as LinearLayout; 

     var removeButton = view.FindViewById(Resource.Id.btnRemove) as Button; 

     removeButton.Click += (s, e) => { 
      var originalView = (View)s; 
      var originalItem = originalView.Tag as MvxJavaContainer<OrderLineItem>; 
      Items.Remove(originalItem); 
      this.NotifyDataSetChanged(); 
     }; 
    } 

    // ........... 
    var tagButton = view.FindViewById(Resource.Id.btnRemove) as Button; 
    tagButton.Tag = new MvxJavaContainer<OrderLineItem>(item); 

    return view; 
} 

注:

  • 重要的是,Click事件處理程序只能設置一次 - 不是一個視圖中使用和重用每一次設置。
  • 我決定使用Remove而不是RemoveAt,因爲我覺得在N項被移除的情況下(N + 1變成N,N + 2變成N + 1等),我覺得更容易跟蹤。但是,我認爲你可以很容易使用RemoveAt移除(我認爲NotifyDataSetChanged通話將重置所有顯示的列表視圖項目)
  • 我已經用於標記字段這個簡單JavaContainer - https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Binding.Droid/MvxJavaContainer.cs
  • 如果您需要使用標籤進行其他目的然後Android/MonoDroid允許您存儲多個標籤使用SetTag(key,obj)
+0

謝謝斯圖爾特。您可能需要更新view.Tag = ...以在按鈕上設置標籤,因爲(s,e)=> {s - 等於按鈕作爲發件人。 – Sam

+0

已修復。謝謝。你也許會發現在某些時候內聯函數可能導致內存泄漏 - 我仍然不確定我是否理解這個錯綜複雜的內容! – Stuart