Android Xamarin可扩展回收视图,如何创建ChildClickListener

Android Xamarin可扩展回收视图,如何创建ChildClickListener,android,xamarin,Android,Xamarin,在上述库的帮助下,我能够实现一个可扩展的RecyclerView,扩展和折叠都很好。现在,我需要为孩子和家长使用不同的单击侦听器。我能够实现一个点击监听器,但是我很难找到子位置和父位置 适配器内可用的位置整数变量仅在正常RecyclerView的情况下返回整体位置。单击父项和子项时,它会根据父项是展开还是折叠返回不同的值 我真正想要的是,当我单击一个父对象时,我想要父对象的位置。当我单击一个子对象时,我需要父对象和子对象的位置 这是我的适配器类 public class LeftNavAdapt

在上述库的帮助下,我能够实现一个可扩展的RecyclerView,扩展和折叠都很好。现在,我需要为孩子和家长使用不同的单击侦听器。我能够实现一个点击监听器,但是我很难找到子位置和父位置

适配器内可用的位置整数变量仅在正常RecyclerView的情况下返回整体位置。单击父项和子项时,它会根据父项是展开还是折叠返回不同的值

我真正想要的是,当我单击一个父对象时,我想要父对象的位置。当我单击一个子对象时,我需要父对象和子对象的位置

这是我的适配器类

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