2014-03-04 3 views
0

내가이 링크에 그림에 보이는 같은 multiselected의 ListView를 만들 시도하고있다 : 왼쪽 상단 모서리에있는 ListViewItem 레이아웃의 체크 박스를 선택하지 않은 사용자가 체크되지 않은 상태로 변경해야합니다 picture . 활동에사용자 정의 multiselected 목록보기 안드로이드

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); 
    } 

하지만 난 문제에 직면 : 지금은 그것을 사용 가 어떻게 레이아웃을 변경할 때 사용자 확인란을 선택하지? Adapter에서 CheckedChange 이벤트 처리를 시도했지만이 ListViewItem의 위치를 ​​어떻게 알 수 있습니까? 내 솔루션이 나에게 좋지 않은 것 같은데, 어떻게하면 좋을지 조언 해주세요. C# 또는 Java에 간단한 예제를 보여 주면 궁금합니다. 감사합니다.

답변

0

나는 당신을 도울 수있는 간단한 예제를 만들었습니다. 목록이고 각 목록 항목에는 TextView 및 CheckBox가 있습니다. 확인란이 선택되어 있는지 여부에 따라 텍스트보기에서 위치가 녹색 또는 빨간색으로 표시됩니다. 문제의 단순화 된 버전입니다. 최선의 해결책인지는 모르겠지만 효과가있을 것입니다.

유의 사항. 체크 박스를 바인딩 할 때보기가 다시 사용되므로 CheckedChange 이벤트를 트리거 할 수 있습니다. 그래서 바인딩을 할 때 태그가 먼저 변경됩니다.

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; } 
     } 
    } 
} 
관련 문제