扩展名列表中的OnChildClick不会触发

时间:2012-05-11 06:03:06

标签: xamarin.android

我遇到的问题是我花了太多时间试图找出答案。单击ExpandableListAdapter中的某个子项时,无法触发OnChildClick侦听器。

我的理解是,当点击其中一个子行时,下面的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);
    }
}

CheckListItemAdapter.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; }
    }
}

2 个答案:

答案 0 :(得分:1)

我自己尝试重现这一点,据我所知,这是当前版本的Mono for Android中的一个错误。我提交了一个带有repro应用程序的bug report to Xamarin,以及一个正在运行的Java等效应用程序。

也就是说,当你点击一个可以使用的项目时,还有另一种选择。您可以在适配器的Click方法中为视图分配GetChildView事件的处理程序:

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

答案 1 :(得分: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>

单独这样做并没有解决问题。接下来是添加到复选框列表中的click事件的可移除性。

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

执行这两项更改后,事件可以一直传播到活动本身。

我希望这些信息将来会帮助其他人。不确定这是否与设计一致。

Chaitanya Marvici

相关问题