2012-05-11 36 views
1

我遇到了一個問題,我花了太多時間試圖弄清楚。當我單擊ExpandableListAdapter中的某個子項時,我無法觸發OnChildClick偵聽器。OnChildClick ExpandableListActivity內部不會觸發

這是我的理解,當點擊其中一行的子節點時,下面的ViewCheckListActivity.cs文件的重寫的OnChildClick事件應該被觸發。我敢肯定,我錯過了一些愚蠢的東西,但是想知道是否有人有任何經驗,並且可以指出我正確的方向來實現這一目標。

代碼是所有列舉如下:

CheckListItem_Group.axml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/loGroup" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:minWidth="25px" 
    android:minHeight="25px"> 
    <CheckedTextView 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="20px" 
     android:paddingLeft="35dip" 
     android:textStyle="bold" 
     android:textSize="14dip" 
     android:gravity="center_vertical" 
     android:layout_gravity="right" 
     android:drawableRight="?android:attr/listChoiceIndicatorMultiple" 
     android:id="@+id/chkCheckList" /> 
</LinearLayout> 

CheckListItem_Item.axml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/loItem" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:minWidth="25px" 
    android:minHeight="25px"> 
    <CheckedTextView 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="20px" 
     android:paddingLeft="35dip" 
     android:textStyle="bold" 
     android:textSize="14dip" 
     android:gravity="center_vertical" 
     android:layout_gravity="right" 
     android:clickable="false" 
     android:focusable="true" 
     android:drawableRight="?android:attr/listChoiceIndicatorMultiple" 
     android:id="@+id/chkCheckListItem" /> 
</LinearLayout> 

ViewCheckListActivity.cs

public class ViewCheckListActivity : ExpandableListActivity 
{ 
    private Int32? _checkListId; 
    protected static DiversLogDao Dao; 

    protected override void OnCreate(Bundle bundle) 
    { 
     base.OnCreate(bundle); 

     var checkListItems = Dao.GetCheckListItems(_checkListId.Value); 

     var adapter = new CheckListItemAdapter(this, checkListItems); 
     SetListAdapter(adapter); 

     ExpandableListView.ChoiceMode = ChoiceMode.Multiple; 
     ExpandableListView.SetOnChildClickListener(this); 
    } 

    public override bool OnChildClick (ExpandableListView parent, View v, int groupPosition, int childPosition, long id) 
    { 
     return base.OnChildClick (parent, v, groupPosition, childPosition, id); 
    } 
} 

CheckListItem Adapter.cs

public class CheckListItemAdapter : BaseExpandableListAdapter 
{ 
    private readonly List<Item> _checkListItems; 
    public readonly Activity Context; 

    public CheckListItemAdapter(Activity context, List<CheckListItem> checkListItems) 
    { 
     _checkListItems = 
      checkListItems.Where(i => i.ParentId == null) 
       .Select(i => new Item 
            { 
             Id = i.Id, 
             Name = i.Name, 
             Description = i.Description, 
             ChildItems = checkListItems.Where(c => c.ParentId == i.Id) 
              .Select(c => new ChildItem 
                  { 
                   Id = c.Id, 
                   CheckListId = c.CheckListId, 
                   ParentId = c.ParentId, 
                   Name = c.Name, 
                   Description = c.Description, 
                   LastUpdated = c.LastUpdated, 
                   Checked = false 
                  }).ToList() 
            }).ToList(); 
     Context = context; 
    } 

    public override View GetGroupView(int groupPosition, bool isExpanded, View convertView, ViewGroup parent) 
    { 
     if (convertView == null) 
     { 
      convertView = Context.LayoutInflater.Inflate(Resource.Layout.CheckListItem_Group, null) as LinearLayout; 
     } 

     if (convertView != null) 
     { 
      var checkList = convertView.FindViewById<CheckedTextView>(Resource.Id.chkCheckList); 
      checkList.SetText(_checkListItems[groupPosition].Name, TextView.BufferType.Normal); 
      checkList.Checked = _checkListItems[groupPosition].AllChildrenChecked(); 
     } 

     return convertView; 
    } 

    public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent) 
    { 
     if(convertView == null) 
     { 
      convertView = Context.LayoutInflater.Inflate(Resource.Layout.CheckListItem_Item, parent, false) as LinearLayout; 
     } 

     if (convertView != null) 
     { 
      var checkListItem = convertView.FindViewById<CheckedTextView>(Resource.Id.chkCheckListItem); 
      checkListItem.SetText(_checkListItems[groupPosition].ChildItems[childPosition].Name, TextView.BufferType.Normal); 
      checkListItem.Checked = _checkListItems[groupPosition].ChildItems[childPosition].Checked; 
      checkListItem.Tag = _checkListItems[groupPosition].ChildItems[childPosition]; 

      checkListItem.Click -= CheckListItemClick; 
      checkListItem.Click += CheckListItemClick; 
     } 

     return convertView; 
    } 

    protected void CheckListItemClick(object sender, EventArgs e) 
    { 
     var chkItem = sender as CheckedTextView; 

     if (chkItem == null) return; 

     chkItem.Toggle(); 

     var childItem = chkItem.Tag as ChildItem; 

     if (childItem == null) return; 

     childItem.Checked = chkItem.Checked; 
    } 

    public override Object GetChild(int groupPosition, int childPosition) 
    { 
     return _checkListItems[groupPosition].ChildItems[childPosition]; 
    } 

    public override long GetChildId(int groupPosition, int childPosition) 
    { 
     return _checkListItems[groupPosition].ChildItems[childPosition].Id; 
    } 

    public override int GetChildrenCount(int groupPosition) 
    { 
     return _checkListItems[groupPosition].ChildItems.Count(); 
    } 

    public override Object GetGroup(int groupPosition) 
    { 
     return _checkListItems[groupPosition]; 
    } 

    public override long GetGroupId(int groupPosition) 
    { 
     return _checkListItems[groupPosition].Id; 
    } 

    public override bool IsChildSelectable(int groupPosition, int childPosition) 
    { 
     return true; 
    } 

    public override int GroupCount 
    { 
     get { return _checkListItems.Count(); } 
    } 

    public override bool HasStableIds 
    { 
     get { return true; } 
    } 

    private class Item : Object 
    { 
     public Int32 Id { get; set; } 
     public String Name { get; set; } 
     public String Description { get; set; } 
     public List<ChildItem> ChildItems { get; set; } 

     public bool AllChildrenChecked() 
     { 
      return ChildItems.All(i => i.Checked); 
     } 
    } 

    private class ChildItem : Object 
    { 
     public Int32 Id { get; set; } 
     public Int32 CheckListId { get; set; } 
     public Int32? ParentId { get; set; } 
     public String Name { get; set; } 
     public String Description { get; set; } 
     public DateTime LastUpdated { get; set; } 
     public Boolean Checked { get; set; } 
    } 
} 

回答

1

我能夠最終得到這個工作。以下是我所做的工作。

首先是可聚焦屬性添加到佈局的項目,如下圖所示:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/loItem" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:focusable="false" 
    android:minWidth="25px" 
    android:minHeight="25px"> 
    <CheckedTextView 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="20px" 
     android:paddingLeft="35dip" 
     android:textStyle="bold" 
     android:textSize="14dip" 
     android:gravity="center_vertical" 
     android:layout_gravity="right" 
     android:focusable="false" 
     android:drawableRight="?android:attr/listChoiceIndicatorMultiple" 
     android:id="@+id/chkCheckListItem" /> 
</LinearLayout> 

而且

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/loGroup" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:focusable="false" 
    android:minWidth="25px" 
    android:minHeight="25px"> 
    <CheckedTextView 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="20px" 
     android:paddingLeft="35dip" 
     android:textStyle="bold" 
     android:textSize="14dip" 
     android:gravity="center_vertical" 
     android:layout_gravity="right" 
     android:focusable="false"  
     android:drawableRight="?android:attr/listChoiceIndicatorMultiple" 
     android:id="@+id/chkCheckList" /> 
</LinearLayout> 

這樣做,僅僅沒有解決問題。接下來是添加到複選框列表中的可移動的點擊事件。

checkListItem.Click -= CheckListItemClick; 
checkListItem.Click += CheckListItemClick; 

做這兩個更改允許事件一直傳播到活動本身。

我只希望這些信息能夠幫助別人在未來。不知道這是否符合設計。

Chaitanya Marvici

1

我想這個重現自己,至於我可以告訴,這是在當前版本的單聲道Android的一個bug。我提交了一個bug report to Xamarin的repro應用程序,以及一個正在運行的Java應用程序。

也就是說,還有另一個選項可以在單擊某個項目時使用。您可以在適配器的GetChildView方法的視圖指定爲Click事件的處理程序:

public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent) 
{ 
    // ...existing code in this method... 

    convertView.Click += delegate 
    { 
     // do stuff 
    }; 

    return convertView; 
} 
+0

我沒有嘗試過,但它絕對是很好的知道。經過多日的努力,我能夠正常工作。不知道我發現的內容是否符合設計要求,但很高興能夠更新您提交的缺陷,如果需要的話。 –

相關問題