i building notifications list application i'm working on , i'm having trouble finding way take list of notifications server , displaying them in separate lists in recyclerview. end product display list of notifications headers recent notifications , older notifications, 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 images, actual notification details , dividers.
i have code displays them in 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 load notifications..."); } }); }
this works fine enough display of notifications , they're sorted in order newest oldest descending. each has boolean property "acknowledged" set false if user hasn't seen them before. want put split list 2 groups i've explained above using flag, don't know how throw in headers. i've thought subclassing notification create notificationheader views , inserting them list appropriate feels sloppy me. i've thought doing 2 recycler views, 1 new , old, visually didn't work way intended (i haven't confirmed looked each recycler view scrolled independently of others, not want). suggestions?
i know first idea of creating special notification headers work, i've done before, feels bad practice.
recyclerview.adapter has method called getitemviewtype() takes position of item in adapter's list, , returns view type should use. in case, method looks 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; }
which checks items in notification list , sees if they're special static 'header notification' object. used internally adapter class , passes 'viewtype' parameter oncreateviewholder() method, 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); }
overriding method allows use viewtype parameter choose appropriate layout inflate viewholder.
there better style/good practice decisions things should have done here, such making notification adapter hold list of notificationlistitems instead of notifications, allow me put in new kind of notificationheader object on it's own instead of making notification objects weren't notifications , using bunch of constant values. underlying principle still there:
- in model, have method returns layout view use it
- in adapter override getitemviewtype() use aforementioned method , return int corresponds layout should inflated
- in adapter override oncreateviewholder() use int getitemviewtype() , inflate appropriate view accordingly
Comments
Post a Comment