ExpandableListActivity 内的 OnChildClick 不会触发 [英] OnChildClick inside ExpandableListActivity does not fire
问题描述
我遇到了一个问题,我花了太多时间试图弄明白.单击 ExpandableListAdapter 中的子项之一时,我无法触发 OnChildClick 侦听器.
I am having an issue that I have spend way too much time trying to figure out. I can't get the OnChildClick listener to fire when one of the child items in my ExpandableListAdapter is clicked.
据我了解,当单击子行中的一行时,应触发以下 ViewCheckListActivity.cs 文件的重写 OnChildClick 事件.我确定我遗漏了一些愚蠢的东西,但想知道是否有人有任何经验并且可以为我指明正确的方向以使其正常工作.
It was my understanding that the overridden OnChildClick event of the ViewCheckListActivity.cs file below should fire when one of the rows of the children are clicked. I'm sure that I am missing something silly, but was wondering if anyone had any experience and could point me in the right direction for getting this working.
代码如下:
CheckListItem_Group.axml
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
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
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
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; }
}
}
推荐答案
我终于让这个工作了.这是我为使其正常工作所做的工作.
I was able to finally get this working. Here is what I did to get it working.
首先是为布局项添加focusable属性,如下所示:
The first was to add the focusable attribute to the layouts items as shown below:
<?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>
单独这样做并不能解决问题.接下来是可移除添加到复选框列表的点击事件.
Doing that alone didn't fix the issue. The next thing is the removable of the click event added to the checkbox list.
checkListItem.Click -= CheckListItemClick;
checkListItem.Click += CheckListItemClick;
执行这 2 个更改允许事件一直传播到活动本身.
Doing those 2 changes allowed the event to propagate all the way up to the activity itself.
我只是希望这些信息将来能帮助其他人.不确定这是否符合设计.
I just hope that this information will help someone else out in the future. Not sure if this is as designed or not.
柴坦尼亚马尔维奇
这篇关于ExpandableListActivity 内的 OnChildClick 不会触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!