使用SortedDictionary填充分段的RecyclerView,ViewHolders下的部分未显示

时间:2018-03-24 18:17:36

标签: c# android xamarin android-recyclerview xamarin.forms

我目前正在尝试弄清楚如何创建事件列表,其中事件由DateTime划分。我的解决方案基于thetonrifles的Java解决方案,但是使用for循环将他的hashmap重建为一维ArrayList<ListItem>。在我的“解决方案”中,我试图完全忽略这个以及对自定义ListItem类或其子类的需求,因为我认为它们完全没有必要。有一个不必要的for循环可能会减慢速度。

我已经能够按照每个DateTime键的事件进行迭代,但是当我尝试使用OnCreateViewHolder()和{{1}手动触发OnBindViewHolder()CreateViewHolder()时函数,Recyclerview不会使用新的BindViewHolder()更新。

以下是EventViewHolder的扩展名:

RecyclerView.Adapter

有两种可能的原因:

  1. 我将错误的位置传递给public class EventsRecyclerViewAdapter : RecyclerView.Adapter { public SortedDictionary<DateTime, List<Event>> EventDictionary { get; set; } private const int TYPE_HEADER = 0; private const int TYPE_EVENT = 1; ViewGroup viewGroupHelper; public override int ItemCount => this.EventDictionary.Count; public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.From(parent.Context); View itemView; viewGroupHelper = parent; if (viewType == TYPE_HEADER) { itemView = layoutInflater.Inflate(Resource.Layout.view_eventlist_header, parent, false); return new HeaderViewHolder(itemView); } itemView = layoutInflater.Inflate(Resource.Layout.view_eventlist_event, parent, false); return new EventViewHolder(itemView); } public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder is EventViewHolder) { EventViewHolder eViewHolder = holder as EventViewHolder; eViewHolder.EventTitle.Text = "Test"; return; } HeaderViewHolder hViewHolder = holder as HeaderViewHolder; DateTime eventStartGroup = EventDictionary.Keys.ElementAt(position); hViewHolder.EventStartGroup.Text = (DateTime.Today == eventStartGroup) ? "Today" : eventStartGroup.ToString("dd MMMM yyyy"); List<Event> eventsUnderDate = EventDictionary.Values.ElementAt(position); FillEventsUnderDate(viewGroupHelper, position, eventsUnderDate); } private void FillEventsUnderDate(ViewGroup parent, int position, List<Event> events) { foreach (Event @event in events) { EventViewHolder holder = CreateViewHolder(parent, TYPE_EVENT) as EventViewHolder; BindViewHolder(holder, position++); } } private class HeaderViewHolder : RecyclerView.ViewHolder { public TextView EventStartGroup { get; set; } public HeaderViewHolder(View itemView) : base(itemView) { EventStartGroup = itemView.FindViewById<TextView>(Resource.Id.eventlist_header); } } private class EventViewHolder : RecyclerView.ViewHolder { public TextView EventTitle { get; set; } public EventViewHolder(View itemView) : base(itemView) { EventTitle = itemView.FindViewById<TextView>(Resource.Id.eventlist_event); } } } (疯狂猜测但确定的情况)
  2. 我只是忘记了事件监听器内部会导致BindViewHolder()无法显示的内容
  3. 现在这可能接近XY问题了。基于thetonrifles的代码构建解决方案可以很好地使用漂亮的ViewHolder等,但我想知道我的代码中缺少什么导致我的CardView缺席s应该举行各自的活动。省略额外的for循环是合理的,应该是可能的,对吗?

    修改

    由于上一次编辑,我所要求的内容更加清晰。这不是“如何创建事件列表,事件按EventViewHolder划分?”,而是“为什么我的DateTime未显示日期部分?”。我明白为什么这个问题在某些情况下必须“更简洁”,但编辑第一句必须至少混淆了一个人。

    这就是我的RecyclerView目前的样子。它显示HeaderViewHolders,但不显示EventViewHolders。在这种情况下,缺少EventViewHolder是我需要帮助的:

    EventViewHolder not showing

1 个答案:

答案 0 :(得分:0)

从您的代码中,您通过FillEventsUnderDate填写数据,在此方法中,您通过调用CreateViewHolderBindViewHolder来填充数据。是的,它最终产生了EventViewHolder

public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
    ...
    FillEventsUnderDate(viewGroupHelper, position, eventsUnderDate);
}

private void FillEventsUnderDate(ViewGroup parent, int position, List<Event> events)
{   
    foreach (Event @event in events)
    {
        //this holder is never used by RecyclerView
        EventViewHolder holder = CreateViewHolder(parent, TYPE_EVENT) as EventViewHolder;
        BindViewHolder(holder, position++);
    }
}

但那又怎么样? EventViewHolder 从未使用过生成的RecyclerView

如果您引用source codes of RecyclerView(lines:1301-1309),则CreateViewHolder会被适配器调用,并会创建RecyclerView使用的持有者。因此,由于这是使用RecyclerView的错误方向,我对此问题没有任何解决方案。我只能建议尝试其他方式来解决需求。