using Android.Views;
using AndroidX.RecyclerView.Widget;
using System.Collections.Generic;
namespace System.Application.UI.Adapters
{
///
/// 的通用基类
///
public abstract class BaseRecycleViewAdapter :
RecyclerView.Adapter, IAdapter
where TViewHolder : BaseViewHolder
where TViewType : struct, IConvertible
{
protected IList? viewModels;
public virtual IList ViewModels
{
get
{
if (viewModels == null)
{
ICreateViewModels i = this;
viewModels = i.CreateViewModels();
}
return viewModels;
}
set => viewModels = value;
}
public IAdapter Interface => this;
public event EventHandler>? ItemClick;
public event EventHandler>? ItemLongClick;
public override int ItemCount => ViewModels.Count;
#region ItemClick/ItemLongClick
///
/// 是否禁用点击事件绑定(包含[点击]与[长按点击])
/// 默认值:
///
protected virtual bool DisableSetItemClickListener => false;
protected virtual ItemClickEventArgs? GetItemClickEventArgs(View view, TViewHolder holder, View.LongClickEventArgs? longClickEventArgs = null)
{
var position = holder.AdapterPosition;
if (position < 0 || position >= ViewModels.Count) return null;
var current = ViewModels[position];
return new PlatformItemClickEventArgs(view, position, current, longClickEventArgs);
}
///
/// 设置列表项的点击事件(ItemClick/ItemLongClick)
///
///
protected virtual void SetItemClicks(TViewHolder holder)
{
if (DisableSetItemClickListener) return;
View? itemClickView = null;
#region ItemClick
if (holder.ItemClickable)
{
itemClickView = holder.ItemView.FindViewById(holder.ItemClickId) ?? holder.ItemView;
if (!itemClickView.Focusable) itemClickView.Focusable = true;
if (!itemClickView.Clickable) itemClickView.Clickable = true;
itemClickView.Click += (sender, _) =>
{
var eventArgs = GetItemClickEventArgs(itemClickView, holder);
if (eventArgs != null)
{
ItemClick?.Invoke(sender, eventArgs);
}
};
}
#endregion
#region ItemLongClick
if (holder.ItemLongClickable)
{
View? itemLongClickView;
if (itemClickView != null && holder.ItemClickId == holder.ItemLongClickId)
{
itemLongClickView = itemClickView;
}
else
{
itemLongClickView = holder.ItemView.FindViewById(holder.ItemLongClickId) ?? holder.ItemView;
}
if (!itemLongClickView.Focusable) itemLongClickView.Focusable = true;
if (!itemLongClickView.LongClickable) itemLongClickView.LongClickable = true;
itemLongClickView.LongClick += (sender, e) =>
{
var eventArgs = GetItemClickEventArgs(itemLongClickView, holder, e);
if (eventArgs != null)
{
ItemLongClick?.Invoke(sender, eventArgs);
}
};
}
#endregion
}
#endregion
#region OnCreateViewHolder
public virtual int? GetLayoutResource(TViewType viewType) => null;
public virtual TViewHolder OnCreateViewHolder(View itemView, TViewType viewType)
{
var holder = (TViewHolder)Activator.CreateInstance(typeof(TViewHolder), itemView);
return holder;
}
public virtual TViewHolder OnCreateViewHolder(TViewType viewType, ViewGroup parent)
{
int layoutResource;
layoutResource = GetLayoutResource(viewType).ThrowIsNull(nameof(layoutResource));
var layoutInflater = LayoutInflater.From(parent.Context);
if (layoutInflater == null) throw new ArgumentNullException(nameof(layoutInflater));
var view = layoutInflater.Inflate(layoutResource, parent, false);
if (view == null) throw new ArgumentNullException(nameof(view));
var holder = OnCreateViewHolder(view, viewType);
return holder;
}
public sealed override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var viewType2 = viewType.ConvertToEnum();
var holder = OnCreateViewHolder(viewType2, parent);
SetItemClicks(holder);
return holder;
}
#endregion
#region OnBindViewHolder
public abstract void OnBindViewHolder(TViewHolder holder, TViewModel item, int position);
public sealed override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
var item = ViewModels[position];
var viewHolder = holder.Cast();
OnBindViewHolder(viewHolder, item, position);
}
#endregion
#region CreateViewModels
protected abstract IList CreateViewModels();
protected abstract IList CreateViewModels(IEnumerable newViewModels);
IList ICreateViewModels.CreateViewModels() => CreateViewModels();
IList ICreateViewModels.CreateViewModels(IEnumerable newViewModels) => CreateViewModels(newViewModels);
#endregion
}
}