Android Xamarin可扩展回收视图,如何创建ChildClickListener
在上述库的帮助下,我能够实现一个可扩展的RecyclerView,扩展和折叠都很好。现在,我需要为孩子和家长使用不同的单击侦听器。我能够实现一个点击监听器,但是我很难找到子位置和父位置 适配器内可用的位置整数变量仅在正常RecyclerView的情况下返回整体位置。单击父项和子项时,它会根据父项是展开还是折叠返回不同的值 我真正想要的是,当我单击一个父对象时,我想要父对象的位置。当我单击一个子对象时,我需要父对象和子对象的位置 这是我的适配器类Android Xamarin可扩展回收视图,如何创建ChildClickListener,android,xamarin,Android,Xamarin,在上述库的帮助下,我能够实现一个可扩展的RecyclerView,扩展和折叠都很好。现在,我需要为孩子和家长使用不同的单击侦听器。我能够实现一个点击监听器,但是我很难找到子位置和父位置 适配器内可用的位置整数变量仅在正常RecyclerView的情况下返回整体位置。单击父项和子项时,它会根据父项是展开还是折叠返回不同的值 我真正想要的是,当我单击一个父对象时,我想要父对象的位置。当我单击一个子对象时,我需要父对象和子对象的位置 这是我的适配器类 public class LeftNavAdapt
public class LeftNavAdapter : ExpandableRecyclerAdapter<LeftNavParentViewHolder, LeftNavChildViewHolder>
{
LayoutInflater _inflater;
public event EventHandler<int> ItemClick;
public LeftNavAdapter(Context context, List<IParentObject> itemList) : base(context, itemList)
{
_inflater = LayoutInflater.From(context);
}
#region implemented abstract members of ExpandableRecyclerAdapter
public override LeftNavParentViewHolder OnCreateParentViewHolder(ViewGroup parentViewGroup)
{
var view = _inflater.Inflate(Resource.Layout.left_nav_item_parent, parentViewGroup, false);
return new LeftNavParentViewHolder(view);
}
public override LeftNavChildViewHolder OnCreateChildViewHolder(ViewGroup childViewGroup)
{
var view = _inflater.Inflate(Resource.Layout.left_nav_item_child, childViewGroup, false);
return new LeftNavChildViewHolder(view, OnChildClick);
}
public override void OnBindParentViewHolder(LeftNavParentViewHolder parentViewHolder, int position, object parentObject)
{
var parent = (LeftNavParent)parentObject;
parentViewHolder.nameTextView.Text = parent.title;
parentViewHolder.imageImageView.SetImageResource(parent.image);
if (parent.ChildObjectList.Count == 0)
parentViewHolder.exapandCollapseButton.Visibility = ViewStates.Gone;
}
public override void OnBindChildViewHolder(LeftNavChildViewHolder childViewHolder, int position, object childObject)
{
var child = (LeftNavChild) childObject;
childViewHolder.cNameTextView.Text = child.childTitle;
//childViewHolder._crimeSolvedCheckBox.CheckedChange += (object sender, CompoundButton.CheckedChangeEventArgs e) =>
//{
// Console.WriteLine("Child CheckedChanged Position: {0}", position);
//};
}
#endregion
private void OnChildClick(int position)
{
Console.WriteLine("checkpoint 2");
if (ItemClick != null)
{
Console.WriteLine("checkpoint 3");
ItemClick(this, position);
Console.WriteLine("checkpoint 4");
}
}
public override void OnParentItemClickListener(int position)
{
Toast.MakeText(_context, position + "touched", ToastLength.Short).Show();
if (_itemList[position] is IParentObject)
{
var parentObject = (IParentObject)_itemList[position];
if (parentObject.ChildObjectList.Count != 0)
{
ExpandParent(parentObject, position);
}
}
}
}
公共类LeftNavAdapter:ExpandableRecyclerAdapter
{
充气机;
公共事件事件处理程序项单击;
公共LeftNavAdapter(上下文上下文,列表项列表):基(上下文,项列表)
{
_充气器=充气器。从(上下文);
}
#区域实现了ExpandableRecyclerAdapter的抽象成员
公共覆盖LeftNavParentViewHolder OnCreateParentViewHolder(视图组parentViewGroup)
{
var视图=\u充气器.Inflate(Resource.Layout.left\u nav\u item\u parentViewGroup,false);
返回新的LeftNavParentViewHolder(视图);
}
公共覆盖LeftNavChildViewHolder OnCreateChildViewHolder(视图组childViewGroup)
{
var view=\u充气器.充气(Resource.Layout.left\u导航\u项目\u子项,子视图组,false);
返回新的LeftNavChildViewHolder(视图,OnChildClick);
}
公共覆盖无效OnBindParentViewHolder(LeftNavParentViewHolder parentViewHolder,int位置,对象parentObject)
{
var parent=(LeftNavParent)parentObject;
parentViewHolder.nameTextView.Text=parent.title;
parentViewHolder.ImageView.SetImageResource(parent.image);
if(parent.ChildObjectList.Count==0)
parentViewHolder.exapandCollapseButton.Visibility=ViewStates.Gone;
}
公共覆盖无效OnBindChildViewHolder(LeftNavChildViewHolder childViewHolder,int位置,对象childObject)
{
var child=(LeftNavChild)childObject;
childViewHolder.cNameTextView.Text=child.childTitle;
//childViewHolder.\u crimeSolvedCheckBox.CheckedChange+=(对象发送者,CompoundButton.CheckedChangeEventArgs e)=>
//{
//WriteLine(“子CheckedChanged位置:{0}”,位置);
//};
}
#端区
私有void OnChildClick(int位置)
{
控制台写入线(“检查点2”);
如果(ItemClick!=null)
{
控制台写入线(“检查点3”);
项目点击(此,位置);
控制台写入线(“检查点4”);
}
}
公共覆盖无效OnParentItemClickListener(int位置)
{
Toast.MakeText(_context,position+“Toast”,ToastLength.Short).Show();
如果(_itemList[position]是IParentObject)
{
var parentObject=(IParentObject)_itemList[position];
if(parentObject.ChildObjectList.Count!=0)
{
ExpandParent(父对象、位置);
}
}
}
}
可扩展RecylerView类
public abstract class ExpandableRecyclerAdapter<PVH, CVH> : RecyclerView.Adapter, IParentItemClickListener
where PVH : ParentViewHolder
where CVH : ChildViewHolder
{
const int TypeParent = 0;
const int TypeChild = 1;
const string StableIdMap = "ExpandableRecyclerAdapter.StableIdMap";
const string StableIdList = "ExpandableRecyclerAdapter.StableIdList";
public const int CustomAnimationViewNotSet = -1;
public const long DefaultRotateDurationMs = 200;
public const long CustomAnimationDurationNotSet = -1;
Dictionary<long, bool> _stableIdMap;
ExpandableRecyclerAdapterHelper _adapterHelper;
IExpandCollapseListener _expandCollapseListener;
bool _parentAndIconClickable = false;
int _customParentAnimationViewId = CustomAnimationViewNotSet;
long _animationDuration = CustomAnimationDurationNotSet;
protected Context _context;
protected List<Object> _itemList;
protected List<IParentObject> _parentItemList;
#region Constructors
public ExpandableRecyclerAdapter(Context context, List<IParentObject> parentItemList)
: this(context, parentItemList, CustomAnimationViewNotSet, DefaultRotateDurationMs)
{
}
public ExpandableRecyclerAdapter(Context context, List<IParentObject> parentItemList,
int customParentAnimationViewId)
: this(context, parentItemList, customParentAnimationViewId, DefaultRotateDurationMs)
{
}
public ExpandableRecyclerAdapter(Context context, List<IParentObject> parentItemList,
int customParentAnimationViewId, long animationDuration)
{
_context = context;
_parentItemList = parentItemList;
_itemList = GenerateObjectList(parentItemList);
_adapterHelper = new ExpandableRecyclerAdapterHelper(_itemList);
_stableIdMap = GenerateStableIdMapFromList(_adapterHelper.HelperItemList);
_customParentAnimationViewId = customParentAnimationViewId;
_animationDuration = animationDuration;
}
#endregion
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup viewGroup, int viewType)
{
if (viewType == TypeParent)
{
var pvh = OnCreateParentViewHolder(viewGroup);
pvh.ParentItemClickListener = this;
return pvh;
}
else if (viewType == TypeChild)
{
return OnCreateChildViewHolder(viewGroup);
}
else
{
throw new ArgumentException("Invalid ViewType found");
}
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
if (_adapterHelper.GetHelperItemAtPosition(position) is ParentWrapper)
{
var parentViewHolder = (PVH)holder;
if (_parentAndIconClickable)
{
if (_customParentAnimationViewId != CustomAnimationViewNotSet &&
_animationDuration != CustomAnimationDurationNotSet)
{
parentViewHolder.SetCustomClickableViewAndItem(_customParentAnimationViewId);
parentViewHolder.AnimationDuration = _animationDuration;
}
else if (_customParentAnimationViewId != CustomAnimationViewNotSet)
{
parentViewHolder.SetCustomClickableViewAndItem(_customParentAnimationViewId);
parentViewHolder.CancelAnimation();
}
else
{
parentViewHolder.SetMainItemClickToExpand();
}
}
else
{
if (_customParentAnimationViewId != CustomAnimationViewNotSet &&
_animationDuration != CustomAnimationDurationNotSet)
{
parentViewHolder.SetCustomClickableViewOnly(_customParentAnimationViewId);
parentViewHolder.AnimationDuration = _animationDuration;
}
else if (_customParentAnimationViewId != CustomAnimationViewNotSet)
{
parentViewHolder.SetCustomClickableViewOnly(_customParentAnimationViewId);
parentViewHolder.CancelAnimation();
}
else
{
parentViewHolder.SetMainItemClickToExpand();
}
}
parentViewHolder.Expanded = ((ParentWrapper)_adapterHelper.GetHelperItemAtPosition(position)).Expanded;
OnBindParentViewHolder(parentViewHolder, position, _itemList[position]);
}
else if (_itemList[position] == null)
{
throw new NullReferenceException("Incorrect ViewHolder found");
}
else
{
OnBindChildViewHolder((CVH)holder, position, _itemList[position]);
}
}
private Dictionary<long, bool> GenerateStableIdMapFromList(List<Object> itemList)
{
var parentObjectHashMap = new Dictionary<long, bool>();
for (int i = 0; i < itemList.Count; i++)
{
if (itemList[i] != null)
{
var parentWrapper = (ParentWrapper)_adapterHelper.GetHelperItemAtPosition(i);
parentObjectHashMap.Add(parentWrapper.StableId, parentWrapper.Expanded);
}
}
return parentObjectHashMap;
}
private List<Object> GenerateObjectList(List<IParentObject> parentObjectList)
{
var objectList = new List<Object>();
foreach (var parentObject in parentObjectList)
{
objectList.Add(parentObject);
}
return objectList;
}
public override int ItemCount
{
get
{
return _itemList.Count;
}
}
public override int GetItemViewType(int position)
{
if (_itemList[position] is IParentObject)
{
return TypeParent;
}
else if (_itemList[position] == null)
{
throw new NullReferenceException("Null object added");
}
else
{
return TypeChild;
}
}
public void SetParentClickableViewAnimationDefaultDuration()
{
_animationDuration = DefaultRotateDurationMs;
}
public long AnimationDuration
{
get { return _animationDuration; }
set { _animationDuration = value; }
}
public int CustomParentAnimationViewId
{
get { return _customParentAnimationViewId; }
set { _customParentAnimationViewId = value; }
}
public bool ParentAndIconExpandOnClick
{
get { return _parentAndIconClickable; }
set { _parentAndIconClickable = value; }
}
public void RemoveAnimation()
{
_customParentAnimationViewId = CustomAnimationViewNotSet;
_animationDuration = CustomAnimationDurationNotSet;
}
public void AddExpandCollapseListener(IExpandCollapseListener expandCollapseListener)
{
_expandCollapseListener = expandCollapseListener;
}
public void ExpandParent(IParentObject parentObject, int position)
{
var parentWrapper = (ParentWrapper)_adapterHelper.GetHelperItemAtPosition(position);
if (parentWrapper == null)
{
return;
}
if (parentWrapper.Expanded)
{
parentWrapper.Expanded = false;
if (_expandCollapseListener != null)
{
var expandedCountBeforePosition = GetExpandedItemCount(position);
_expandCollapseListener.OnRecyclerViewItemCollapsed(position - expandedCountBeforePosition);
}
// Was Java HashMap put, need to replace the value
_stableIdMap[parentWrapper.StableId] = false;
//_stableIdMap.Add(parentWrapper.StableId, false);
var childObjectList = ((IParentObject)parentWrapper.ParentObject).ChildObjectList;
if (childObjectList != null)
{
for (int i = childObjectList.Count - 1; i >= 0; i--)
{
var pos = position + i + 1;
_itemList.RemoveAt(pos);
_adapterHelper.HelperItemList.RemoveAt(pos);
NotifyItemRemoved(pos);
}
}
}
else
{
parentWrapper.Expanded = true;
if (_expandCollapseListener != null)
{
var expandedCountBeforePosition = GetExpandedItemCount(position);
_expandCollapseListener.OnRecyclerViewItemExpanded(position - expandedCountBeforePosition);
}
// Was Java HashMap put, need to replace the value
_stableIdMap[parentWrapper.StableId] = true;
//_stableIdMap.Add(parentWrapper.StableId, true);
var childObjectList = ((IParentObject)parentWrapper.ParentObject).ChildObjectList;
if (childObjectList != null)
{
for (int i = 0; i < childObjectList.Count; i++)
{
var pos = position + i + 1;
_itemList.Insert(pos, childObjectList[i]);
_adapterHelper.HelperItemList.Insert(pos, childObjectList[i]);
NotifyItemInserted(pos);
}
}
}
}
private int GetExpandedItemCount(int position)
{
if (position == 0)
return 0;
var expandedCount = 0;
for (int i = 0; i < position; i++)
{
var obj = _itemList[i];
if (!(obj is IParentObject))
expandedCount++;
}
return expandedCount;
}
public Bundle OnSaveInstanceState(Bundle savedInstanceStateBundle)
{
savedInstanceStateBundle.PutString(StableIdMap, JsonConvert.SerializeObject(_stableIdMap));
return savedInstanceStateBundle;
}
public void OnRestoreInstanceState(Bundle savedInstanceStateBundle)
{
if (savedInstanceStateBundle == null)
return;
if (!savedInstanceStateBundle.ContainsKey(StableIdMap))
return;
_stableIdMap = JsonConvert.DeserializeObject<Dictionary<long, bool>>(savedInstanceStateBundle.GetString(StableIdMap));
var i = 0;
while (i < _adapterHelper.HelperItemList.Count)
{
if (_adapterHelper.GetHelperItemAtPosition(i) is ParentWrapper)
{
var parentWrapper = (ParentWrapper)_adapterHelper.GetHelperItemAtPosition(i);
if (_stableIdMap.ContainsKey(parentWrapper.StableId))
{
parentWrapper.Expanded = _stableIdMap[parentWrapper.StableId];
if (parentWrapper.Expanded)
{
var childObjectList = ((IParentObject)parentWrapper.ParentObject).ChildObjectList;
if (childObjectList != null)
{
for (int j = 0; j < childObjectList.Count; j++)
{
i++;
_itemList.Insert(i, childObjectList[j]);
_adapterHelper.HelperItemList.Insert(i, childObjectList[j]);
}
}
}
}
else
{
parentWrapper.Expanded = false;
}
}
i++;
}
NotifyDataSetChanged();
}
public abstract PVH OnCreateParentViewHolder(ViewGroup parentViewGroup);
public abstract CVH OnCreateChildViewHolder(ViewGroup childViewGroup);
public abstract void OnBindParentViewHolder(PVH parentViewHolder, int position, Object parentObject);
public abstract void OnBindChildViewHolder(CVH childViewHolder, int position, Object childObject);
#region IParentItemClickListener implementation
public abstract void OnParentItemClickListener(int position);
// {
//// if (_itemList[position] is IParentObject)
//// {
//// var parentObject = (IParentObject)_itemList[position];
////if (parentObject.ChildObjectList.Count != 0)
////{
//// ExpandParent(parentObject, position);
////}
//// }
// }
#endregion
}
公共抽象类ExpandableRecyclerAdapter:RecyclerView.Adapter,IParentItemClickListener
其中PVH:ParentViewHolder
其中CVH:ChildViewHolder
{
const int TypeParent=0;
const int TypeChild=1;
常量字符串StableIdMap=“ExpandableRecyclerAdapter.StableIdMap”;
常量字符串StableIdList=“ExpandableRecyclerAdapter.StableIdList”;
public const int CustomAnimationViewNotSet=-1;
public const long defaultrotationems=200;
public const long CustomAnimationDurationNotSet=-1;
字典(stableIdMap),;
可扩展回收设备适配器帮助器(U Adapter Helper);;
IExpandCollapseListener\u expandCollapseListener;
bool\u parentandinclickable=false;
int _customParentAnimationViewId=CustomAnimationViewNotSet;
long _animationDuration=CustomAnimationDurationNotSet;
保护上下文(protectedcontext)上下文;;
受保护列表_itemList;
受保护列表\u parentItemList;
#区域构造函数
公共ExpandableRecyclerAdapter(上下文上下文,列表parentItemList)
:这(上下文、parentItemList、CustomAnimationViewNotSet、DefaultRotatedUserMS)
{
}
公共ExpandableRecyclerAdapter(上下文上下文、列表parentItemList、,
int customParentAnimationViewId)
:这(上下文、parentItemList、customParentAnimationViewId、DefaultRotatedUserMS)
{
}
公共ExpandableRecyclerAdapter(上下文上下文、列表parentItemList、,
int customParentAnimationViewId,长动画持续时间)
{
_上下文=上下文;
_parentItemList=parentItemList;
_itemList=生成对象列表(parentItemList);
_adapterHelper=新的ExpandableRecyclerAdapterHelper(_itemList);
_stableIdMap=GenerateStableIdMapFromList(_adapterHelper.HelperItemList);
_customParentAnimationViewId=customParentAnimationViewId;
_animationDuration=animationDuration;
}
#端区
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup ViewGroup,int viewType)
{
如果(viewType==TypeParent)
{
var pvh=OnCreateParentViewHolder(视图组);
pvh.ParentItemClickListener=this;
返回pvh;
}
else if(viewType==TypeChild)
{
返回OnCreateChildViewHolder(视图组);
}
其他的
{
抛出新ArgumentException(“找到无效的ViewType”);
}
}
公共覆盖无效OnBindViewHolder(RecyclerView.ViewHolder,int位置)
{
如果(_adapterHelper.GetHelperItemPosition(位置)为
public class LeftNavChildViewHolder : ChildViewHolder
{
public TextView cNameTextView;
public LeftNavChildViewHolder(View itemView, Action<int> listener) : base(itemView)
{
cNameTextView = itemView.FindViewById<TextView>(Resource.Id.leftNavTitleChild);
itemView.Click += (sender, e) => listener(Position);
}
}
public class LeftNavAdapter : ExpandableRecyclerAdapter<LeftNavParentViewHolder, LeftNavChildViewHolder>
{
public override LeftNavChildViewHolder OnCreateChildViewHolder(ViewGroup childViewGroup)
{
var view = _inflater.Inflate(Resource.Layout.left_nav_item_child, childViewGroup, false);
return new LeftNavChildViewHolder(view, OnChildClick);
}
void OnChildClick(int position)
{
// Do whatever you want
}
}