OnChildClick внутри ExpandableListActivity не запускается

У меня проблема, которую я трачу слишком много времени, пытаясь разобраться. Я не могу заставить прослушиватель OnChildClick срабатывать при щелчке по одному из дочерних элементов в моем ExpandableListAdapter.

Насколько я понимаю, переопределенное событие OnChildClick файла ViewCheckListActivity.cs, приведенного ниже, должно запускаться при нажатии одной из строк дочерних элементов. Я уверен, что мне не хватает чего-то глупого, но мне было интересно, есть ли у кого-нибудь опыт и мог бы указать мне правильное направление для получения этой работы.

Код все перечислено ниже:

CheckListItem_Group.axml

<code><?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>
</code>

CheckListItem_Item.axml

<code><?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>
</code>

ViewCheckListActivity.cs

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

CheckListItemAdapter.cs

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

Ответы на вопрос(2)

и, насколько я могу судить, это ошибка в текущей версии Mono для Android. Я представилсообщение об ошибке в Xamarin с приложением repro и эквивалентным приложением на 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;
}
 Chaitanya Marvici14 мая 2012 г., 07:58
Я не пробовал этого, но это определенно полезно знать. Я смог заставить его работать должным образом после многих дней борьбы с этим. Не уверен, что то, что я обнаружил, как задумано или нет, но будет рад обновить сообщенную вами ошибку, если это будет необходимо.
Решение Вопроса

чтобы заставить его работать.

Первым было добавить атрибут focusable к элементам макетов, как показано ниже:

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

Выполнение этих двух изменений позволило распространить событие вплоть до самого действия.

Я просто надеюсь, что эта информация поможет кому-то еще в будущем. Не уверен, если это так, как задумано или нет.

Чайтанья Марвичи

Ваш ответ на вопрос