2014-03-04 130 views
0

我一直在試圖建立一個multiselected的ListView像它看起來的圖片在這個環節: picture 當用戶選中在左上角的ListViewItem佈局的複選框必須更改爲未選中狀態。 現在我使用它:自定義列表視圖multiselected的Android

public class ProcedureAdapter : BaseAdapter<Procedure> 
{ 
    List<Procedure> items; 
    Activity context; 
    Dictionary<int, bool> CheckedItems = new Dictionary<int, bool>(); 
    public ProcedureAdapter(Activity context, List<Procedure> items) 
     : base() 
    { 
     this.context = context; 
     this.items = items; 
     for (int i = 0; i < items.Count; i++) 
     { 
      CheckedItems.Add(i, false); 
     } 
    } 
    public override long GetItemId(int position) 
    { 
     return position; 
    } 
    public override Procedure this[int position] 
    { 
     get { return items[position]; } 
    } 
    public override int Count 
    { 
     get { return items.Count; } 
    } 

    public void toggleCheck(int position) 
    { 
     if (CheckedItems.ContainsKey(position)) 
     { 
      CheckedItems[position] = !CheckedItems[position]; 
      base.NotifyDataSetChanged(); 
     } 
    } 
    public override View GetView(int position, View convertView, ViewGroup parent) 
    { 
     var item = items[position]; 
     View view = convertView; 
     if (view == null) 
      view = context.LayoutInflater.Inflate(Resource.Layout.ProcedureListViewItem, null); 

     if (!CheckedItems.ContainsKey(position)) 
      CheckedItems.Add(position, false); 

     if (CheckedItems[position]) 
     { 
      checkBox.Visibility = ViewStates.Visible; 
      checkBox.Checked = true; 
      ProcedureTypeImage.Visibility = ViewStates.Gone; 
     } 
     else 
     { 
      checkBox.Visibility = ViewStates.Gone; 
      checkBox.Checked = false; 
      ProcedureTypeImage.Visibility = ViewStates.Visible; 
     } 



     return view; 
    } 
} 

在活動:

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     var view = inflater.Inflate(Resource.Layout.ProceduresLayout, container, false); 
     listView = view.FindViewById<ListView>(Resource.Id.listView1); 
     listView.ItemLongClick += listView_ItemLongClick; 
     procAdapter = new ProcedureAdapter(Activity, procedures); 
     listView.Adapter = procAdapter; 

     return view; 
    } 

    void listView_ItemLongClick(object sender, AdapterView.ItemLongClickEventArgs e) 
    { 
     procAdapter.toggleCheck(e.Position); 
    } 

但我面臨的問題: 我如何改變佈局時,用戶選中的複選框? 我已經嘗試在適配器中處理CheckedChange事件,但我怎麼知道這個ListViewItem的位置? 我的解決方案對我來說似乎不是很好,請給我建議,我該如何做得更好。 我想知道你是否向我展示了一個關於C#或Java的簡單例子。 謝謝

回答

0

我做了一個簡單的例子,可以幫助你。這是一個列表,每個列表項都有一個TextView和CheckBox。文本視圖以綠色或紅色顯示位置,具體取決於是否勾選複選框。這是你的問題的簡化版本。不知道這是否是最好的解決方案,但它會起作用。

唯一要注意的事情。由於視圖在綁定複選框時被重用,因此可能會觸發CheckedChange事件。這就是爲什麼在進行綁定時第一次更改Tag的原因。

using System.Globalization; 
using Android.App; 
using Android.Graphics; 
using Android.Views; 
using Android.Widget; 
using Object = Java.Lang.Object; 

namespace AndroidApplication1 
{ 
    public class LvAdapter : BaseAdapter 
    { 
     private readonly Activity _context; 
     public bool[] Bools = new bool[15]; 

     public LvAdapter(Activity context) 
     { 
      _context = context; 
     } 

     public override Object GetItem(int position) 
     { 
      return null; 
     } 

     public override long GetItemId(int position) 
     { 
      return position; 
     } 

     public override View GetView(int position, View convertView, ViewGroup parent) 
     { 
      ViewHolder vh; 

      var view = convertView; 
      if (view == null) 
      { 
       view = _context.LayoutInflater.Inflate(Resource.Layout.list_item, parent, false); 
       vh = new ViewHolder(); 
       vh.Initialize(view, this); 
       view.Tag = vh; 
      } 
      vh = view.Tag as ViewHolder; 
      if (vh != null) vh.Bind(position, Bools); 
      return view; 
     } 

     public override int Count 
     { 
      get { return Bools.Length; } 
     } 

     private class ViewHolder : Object 
     { 
      private TextView _text; 
      private CheckBox _check; 

      public void Initialize(View view, LvAdapter adapter) 
      { 
       _text = view.FindViewById<TextView>(Resource.Id.tvText); 
       _check = view.FindViewById<CheckBox>(Resource.Id.cbCheck); 

       _check.CheckedChange += (sender, args) => 
       { 
        var tagHoldr = (((View) sender).Tag) as TagHolder; 
        adapter.Bools[tagHoldr.Positon] = args.IsChecked; 
        tagHoldr.TextView.SetTextColor(args.IsChecked ? Color.Green : Color.Red); 
       }; 
      } 

      public void Bind(int position, bool[] bools) 
      { 
       _check.Tag = new TagHolder { Positon = position, TextView = _text }; 
       _text.Text = position.ToString(CultureInfo.InvariantCulture); 
       _check.Checked = bools[position]; 
       _text.SetTextColor(bools[position] ? Color.Green : Color.Red); 
      } 
     } 

     private class TagHolder : Object 
     { 
      public int Positon { get; set; } 
      public TextView TextView { get; set; } 
     } 
    } 
}