问题描述
我正在为正在处理的应用程序构建通知列表,但我找不到从服务器获取通知列表并将其显示在RecyclerView中单独列表中的方法.最终产品将显示通知列表,其中包含最近的通知"和较旧的通知"的标头,例如:
I am building a notifications list for an application I'm working on and I'm having trouble finding a way to take my list of notifications from the server and displaying them in separate lists in a RecyclerView. The end product would display the list of notifications with headers for Recent notifications and Older notifications, a la:
<RECENT HEADER>
<NOTIF-1>
<NOTIF-2>
<OLDER HEADER>
<NOTIF-3>
<NOTIF-4>
<NOTIF-5>
<NOTIF-6>
除了用尖括号括起来的文字外,它是代表这些文字的实际视图,并带有图像,实际通知详细信息和分隔线.
except instead of angle-bracket text it's actual views representing those, complete with images, actual notification details and dividers.
我已经有在RecyclerView中显示它们的代码:
I already have code that displays them in a RecyclerView:
XML:
<!-- Main layout -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/include_toolbar"/>
<RelativeLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/notification_swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mapjungle.mymoose.ui.widget.EmptyRecyclerView
android:id="@+id/notification_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
</LinearLayout>
Java:
@InjectView(R.id.notification_list) RecyclerView mRecyclerView;
@Inject Picasso mPicasso;
@Inject NotificationService mUserService;
private NotificationAdapter mAdatper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notifications);
ButterKnife.inject(this);
setTitle("Notifications");
mAdatper = new NotificationAdapter(mPicasso);
mRecyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(this)
.color(getResources().getColor(R.color.secondary_color))
.size(1)
.build());
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mAdatper);
updateList();
}
@Override
protected int getSelfNavDrawerItem() {
return NAVDRAWER_ITEM_PHOTO_POST;
}
public void updateList() {
mUserService.getNotifications(new Callback<List<Notification>>() {
@Override
public void success(List<Notification> notificationList, Response response) {
mAdatper.replaceWith(notificationList);
}
@Override
public void failure(RetrofitError error) {
Timber.e(error, "Failed to load notifications...");
}
});
}
这一切都可以很好地显示所有通知,并且按照从最新到最早的降序对它们进行排序.但是每个用户都有一个布尔属性"acknowledged",如果用户以前没有看到过,则将其设置为false.我想使用该标志将列表分成我在上面解释过的两组,但是我不知道如何将标头扔进去.我曾考虑过将Notification子类化以创建NotificationHeader视图,并将它们插入到适当的列表中,但这对我来说很草率.我还考虑过要做两个回收站视图,一个用于新回收站视图,另一个用于旧回收站视图,但是从视觉上看,这并没有达到我的预期目的(我尚未确认,但是看起来每个回收站视图都独立于滚动视图.其他,这是我不想要的东西).有什么建议吗?
This all works fine enough to display all of the notifications and they're all sorted in the order from newest to oldest descending. But each has a boolean property "acknowledged" that is set to false if the user hasn't seen them before. I want to put split the list into the two groups I've explained above using this flag, but I don't know how to throw in the headers. I've thought about subclassing Notification to create NotificationHeader views and inserting them into the list where appropriate but that just feels sloppy to me. I've also thought about doing two recycler views, one for the new and another for the old, but visually that didn't work the way I intended (I haven't confirmed it but it looked like each recycler view scrolled independently of the others, something that I do not want). Any suggestions?
我知道创建特殊的通知标题的第一个想法可能会起作用,我之前做过类似的事情,但这只是一种不好的做法.
I know that the first idea of creating special Notification Headers will probably work, I've done something like that before, but it just feels like bad practice.
推荐答案
RecyclerView.Adapter有一个名为 getItemViewType(),它可以获取项目在适配器列表中的位置,并返回其应使用的视图类型.就我而言,该方法如下所示:
RecyclerView.Adapter has a method called getItemViewType() that takes the position of an item in the adapter's list, and returns the view type it should use. In my case, the method looks like this:
@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'参数传递给 onCreateViewHolder()方法,我们也将其重写:
Which checks the items in the notification list and sees if they're a special static 'Header notification' object. This is used internally by the Adapter class and it passes the 'viewType' parameter to the onCreateViewHolder() method, which we also override:
@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选择合适的布局进行充气.
Overriding this method allows us to use the viewType parameter to choose the appropriate layout to inflate for the ViewHolder.
我应该在这里做一些更好的样式/良好实践决策,例如让我的Notification适配器保存NotificationListItems列表而不是Notifications,这将允许我自己放置一种新的NotificationHeader对象而不是制作不是真正的Notifications的Notification对象,而是使用一堆常量.但是基本原理仍然存在:
There are some better style/good practice decisions things I should have done here, such as making my Notification adapter hold a list of NotificationListItems instead of Notifications, which would allow me to put in a new kind of NotificationHeader object on it's own instead of making Notification objects that weren't really Notifications and using a bunch of constant values. But the underlying principle is still there:
- 在您的模型中,有一个方法可以返回要用于其的布局视图
- 在您的适配器中重写getItemViewType()以使用上述方法,并返回与应放大的布局相对应的int
- 在您的适配器中,还重写onCreateViewHolder()以使用getItemViewType()中的int并相应地为适当的视图充气
这篇关于如何在recyclerview中对列表项进行分类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!