我遇到的问题是我花了太多时间试图找出答案。单击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; }
}
}
答案 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