Android 如何在recyclerview中对列表项进行分类?

Android 如何在recyclerview中对列表项进行分类?,android,notifications,android-recyclerview,Android,Notifications,Android Recyclerview,我正在为正在处理的应用程序构建通知列表,但我很难找到从服务器获取通知列表并将其显示在RecyclerView中的单独列表中的方法。最终产品将显示通知列表,其中包含最近通知和旧通知的标题,la: <RECENT HEADER> <NOTIF-1> <NOTIF-2> <OLDER HEADER> <NOTIF-3> <NOTIF-4> <NOTIF-5> <NO

我正在为正在处理的应用程序构建通知列表,但我很难找到从服务器获取通知列表并将其显示在RecyclerView中的单独列表中的方法。最终产品将显示通知列表,其中包含最近通知和旧通知的标题,la:

<RECENT HEADER>
    <NOTIF-1>
    <NOTIF-2>
<OLDER HEADER>
    <NOTIF-3>
    <NOTIF-4>
    <NOTIF-5>
    <NOTIF-6>

除了角括号文本之外,它是表示这些内容的实际视图,包括图像、实际通知细节和分隔符

我已经有了在RecyclerView中显示它们的代码:

XML:


爪哇:

@InjectView(R.id.notification_list)RecyclerView-mRecyclerView;
@注入毕加索和卡索;
@注入通知服务mUserService;
私人通知适配器制造商;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_通知);
注射(这个);
setTitle(“通知”);
mAdatper=新通知适配器(mPicasso);
mrecycerview.addItemDecoration(新的HorizontalDividerItemDecoration.Builder)(此)
.color(getResources().getColor(R.color.secondary_color))
.尺寸(1)
.build());
最终LinearLayoutManager layoutManager=新的LinearLayoutManager(本);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mAdatper);
updateList();
}
@凌驾
受保护的int-getSelfNavDrawerItem(){
返回NAVDRAWER\u ITEM\u PHOTO\u POST;
}
公共void updateList(){
getNotifications(新回调(){
@凌驾
公共作废成功(列表通知列表、响应){
替换为(通知列表);
}
@凌驾
公共无效失败(错误){
Timber.e(错误,“无法加载通知…”);
}
});
}
这一切都可以很好地显示所有通知,它们都按照从最新到最旧的降序排列。但每一个都有一个布尔属性“已确认”,如果用户以前没有看到过,则该属性设置为false。我想使用这个标志将列表分成我上面解释过的两组,但我不知道如何插入标题。我曾经考虑过将通知子类化以创建NotificationHeader视图,并在适当的地方将它们插入列表中,但我觉得这太草率了。我还考虑过做两个回收器视图,一个用于新视图,另一个用于旧视图,但视觉效果与我的预期不符(我还没有确认,但看起来每个回收器视图都独立于其他视图滚动,这是我不想要的)。有什么建议吗


我知道创建特殊通知头的第一个想法可能会奏效,我以前也做过类似的事情,但这感觉像是一种糟糕的做法。

RecyclerView.Adapter有一个名为的方法,它获取适配器列表中某个项的位置,并返回它应该使用的视图类型。在我的例子中,该方法如下所示:

@Override
public int getItemViewType(int position){
    Notification n = mNotifications.get(position);
    boolean useHeader = n.getType().equals(Notification.HEADER_OLDER) ||
            n.getType().equals(Notification.HEADER_RECENT);
    return useHeader ? this.USE_HEADER : this.DONT_USE_HEADER;
}
它检查通知列表中的项目,并查看它们是否是特殊的静态“标题通知”对象。Adapter类在内部使用它,它将“viewType”参数传递给方法,我们也会覆盖该方法:

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    int layout = viewType ==  USE_HEADER ?
            R.layout.view_item_notification_header :
            R.layout.view_item_notification;

    NotificationItemView view = (NotificationItemView) LayoutInflater.from(viewGroup.getContext())
            .inflate(layout, viewGroup, false);
    return new ViewHolder(view);
}
替代此方法允许我们使用viewType参数为ViewHolder选择适当的充气布局

我应该在这里做一些更好的风格/良好实践决策,比如让我的通知适配器保存NotificationListItems列表而不是通知,这将允许我自己添加一种新的NotificationHeader对象,而不是创建实际上不是通知的通知对象,并使用一组常量值。但基本原则仍然存在:

  • 在模型中,使用一个方法返回要用于该模型的布局视图
  • 在适配器中,重写getItemViewType()以使用前面提到的方法并返回对应于应该膨胀的布局的int
  • 在适配器中,还重写onCreateViewHolder()以使用getItemViewType()中的int,并相应地膨胀相应的视图

  • 嘿,我正试着做类似的事情。你有没有可能发布代码?谢谢张贴:)我还解释了我在做什么。希望这有帮助/不要太冗长。
    @Override
    public int getItemViewType(int position){
        Notification n = mNotifications.get(position);
        boolean useHeader = n.getType().equals(Notification.HEADER_OLDER) ||
                n.getType().equals(Notification.HEADER_RECENT);
        return useHeader ? this.USE_HEADER : this.DONT_USE_HEADER;
    }
    
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        int layout = viewType ==  USE_HEADER ?
                R.layout.view_item_notification_header :
                R.layout.view_item_notification;
    
        NotificationItemView view = (NotificationItemView) LayoutInflater.from(viewGroup.getContext())
                .inflate(layout, viewGroup, false);
        return new ViewHolder(view);
    }