如何借助DynamicData将分组数据转换为扁平集合适配RecyclerView
问题描述
我现有如下SourceCache对象:
private readonly SourceCache<PlainItinerary, string> _itineraries = new SourceCache<PlainItinerary, string>(itinerary => itinerary.ItineraryId);
之前通过DynamicData按日期分组,代码如下:
_itineraries .Connect() .Group(k => { if (k.JourneyStartTime.HasValue) return new DateTimeOffset(k.JourneyStartTime.Value.Date).ToUnixTimeMilliseconds(); else return -1; }) .Transform(group => new ItineraryGroup(group, Disposables)) .Sort(SortExpressionComparer<ItineraryGroup>.Ascending(group => group.Date)) .ObserveOn(MainThread.AppContext) .Bind(ItineraryGroups);
分组结果存储在这个集合中:
public ObservableCollectionExtended<ItineraryGroup> ItineraryGroups {get; set;}
其中ItineraryGroup定义为:
public class ItineraryGroup : ObservableCollectionExtended<PlainItinerary> { }
这段代码原本用于绑定Xamarin.Forms的分组CollectionView,但现在要迁移到Xamarin.Android的RecyclerView,而RecyclerView需要扁平集合。我希望最小改动DynamicData代码,转换成以下结构:
public class ItineraryHeaderItem : BaseItem { public DateTimeOffset Date {get; set;} } public class ItineraryItem : BaseItem { public PlainItinerary Itinerary {get; set;} } public ObservableCollectionExtended<BaseItem> Itineraries {get; set;}
解决方案
你可以通过DynamicData的TransformMany操作,把分组后的结果展开成包含头部和行程项的扁平集合,具体改动如下:
_itineraries .Connect() // 保留原有分组逻辑 .Group(k => { if (k.JourneyStartTime.HasValue) return new DateTimeOffset(k.JourneyStartTime.Value.Date).ToUnixTimeMilliseconds(); else return -1; }) // 基于分组Key转换回日期排序,保证顺序正确 .Sort(SortExpressionComparer<IGroup<string, PlainItinerary>>.Ascending(group => group.Key != -1 ? DateTimeOffset.FromUnixTimeMilliseconds(group.Key).Date : DateTime.MaxValue.Date)) // 将每个分组拆分为头部+行程项的组合 .TransformMany(group => { var items = new List<BaseItem>(); // 为有效日期的分组添加头部 if (group.Key != -1) { items.Add(new ItineraryHeaderItem { Date = DateTimeOffset.FromUnixTimeMilliseconds(group.Key) }); } // 添加分组下的所有行程项 items.AddRange(group.Items.Select(itinerary => new ItineraryItem { Itinerary = itinerary })); return items; }) .ObserveOn(MainThread.AppContext) // 绑定到新的扁平集合 .Bind(Itineraries);
关键改动说明:
- 保留原有的
Group和排序逻辑,确保分组规则和展示顺序与之前一致; - 用
TransformMany替代Transform,将每个分组拆分为一个头部项加多个行程项,实现扁平结构; - 排序时基于分组Key转换回日期进行比较,保证头部的顺序正确;
- 最终绑定到新的
ObservableCollectionExtended<BaseItem>集合,适配RecyclerView的扁平数据需求。
如果需要处理无日期的行程(Key=-1),可以根据需求调整头部逻辑,比如添加“无日期”的头部,或者直接跳过头部只显示行程项。
内容的提问来源于stack exchange,提问作者Pravin Patil
相关产品推荐
相关产品推荐

