java - Is it appropriate to use the Decorator Pattern while extending RecyclerView.Adapter? -
i've written footeradapter
seems work perfectly.
i realised viewholder
has field mposition
among others hold state in each element leading me suspect header not achievable usage of decorator pattern, because hold different position in each adapter
.
that is, except if wrapper/decorator adapter
didn't alter other elements. say: footers ok, long data not need binded them.
if wrapper adapters possible need more access viewholder? i'm not sure how fields
intended usage:
headerview = new view( context ); footerview = new view( context ); myadapter myadapter = new myadapter(); headeradapter headeradapter = new headeradapter( myadapter , headerview ); footeradapter footeradapter = new footeradapter( headeradapter , footerview ); recyclerview recyclerview = new recyclerview(); recyclerview.setadapter( footeradapter );
this cool, because add headers & footers arbitrary adapter
, not have worry indexing , offsetting item counts.
footeradapter.java
public class footeradapter extends recyclerview.adapter { private static final string tag = "footeradapter"; private final recyclerview.adapter<recyclerview.viewholder> wrappedadapter; private view footer; public static final int footer_type = 0x72846fe; public footeradapter( recyclerview.adapter<recyclerview.viewholder> wrappedadapter , view footer ) { this.footer = footer; this.wrappedadapter = wrappedadapter; wrappedadapter.registeradapterdataobserver(new thisobserver()); } @override public int getitemviewtype(int position) { if( position == wrappedadapter.getitemcount() ) return footer_type; return wrappedadapter.getitemviewtype(position); } @override public recyclerview.viewholder oncreateviewholder(viewgroup parent, int viewtype) { if( viewtype == footer_type ) { return new recyclerview.viewholder( footer ){}; }else { return wrappedadapter.oncreateviewholder(parent,viewtype); } } @override public void onbindviewholder(recyclerview.viewholder holder, int position) { if( holder.getitemviewtype() == footer_type ) return; return wrappedadapter.bindviewholder( holder , position ); } @override public int getitemcount() { return wrappedadapter.getitemcount() + 1; } private class thisobserver extends adapterdataobserver { public void onchanged() { notifydatasetchanged(); } public void onitemrangechanged(int positionstart, int itemcount) { notifyitemrangechanged(positionstart,itemcount); } public void onitemrangeinserted(int positionstart, int itemcount) { notifyitemrangeinserted(positionstart,itemcount); } public void onitemrangeremoved(int positionstart, int itemcount) { notifyitemrangeremoved(positionstart,itemcount); } public void onitemrangemoved(int fromposition, int toposition, int itemcount) { int lower = math.min( fromposition , toposition ); int upper = math.max( fromposition , toposition ); for( int = itemcount-1 ; < itemcount ; i++ ) { notifyitemmoved(upper+i,lower+i+(toposition-fromposition)); } } } }
headeradapter.java
public class headeradapter extends recyclerview.adapter { private static final string tag = "headeradapter"; private final recyclerview.adapter<recyclerview.viewholder> wrappedadapter; private view header; public static final int header_type = 0x747efe; public headeradapter( recyclerview.adapter<recyclerview.viewholder> wrappedadapter , view header ) { this.header = header; this.wrappedadapter = wrappedadapter; wrappedadapter.registeradapterdataobserver(new thisobserver()); } @override public int getitemviewtype(int position) { return position == 0 ? header_type : wrappedadapter.getitemviewtype(position - 1); } @override public recyclerview.viewholder oncreateviewholder(viewgroup parent, int viewtype) { if( viewtype == header_type ) { return new recyclerview.viewholder( header ){}; }else { return new recyclerview.viewholder( wrappedadapter.oncreateviewholder(parent,viewtype).itemview ){}; // thought kind of wrapping (hack?) might // around different indexing in different adapters, // doesn't work, needs more // information, or able observe changes in // "child" viewholder. } } @override public void onbindviewholder(recyclerview.viewholder holder, int position) { if( holder.getitemviewtype() != header_type ) wrappedadapter.bindviewholder( holder , position - 1 ); } @override public int getitemcount() { return wrappedadapter.getitemcount() + 1; } private class thisobserver extends recyclerview.adapterdataobserver { public void onchanged() { notifydatasetchanged(); } public void onitemrangechanged(int positionstart, int itemcount) { notifyitemrangechanged(1+positionstart,itemcount); } public void onitemrangeinserted(final int positionstart, final int itemcount) { notifyitemrangeinserted(1 + positionstart, itemcount); } public void onitemrangeremoved(int positionstart, int itemcount) { notifyitemrangeremoved(1 + positionstart, itemcount); } public void onitemrangemoved(int fromposition, int toposition, int itemcount) { fromposition++; toposition++; int lower = math.min( fromposition , toposition ); int upper = math.max( fromposition , toposition ); for( int = itemcount-1 ; < itemcount ; i++ ) notifyitemmoved(upper+i,lower+i+(toposition-fromposition)); } } }
so turns out footer wasn't perfect.
so can't use pattern headers or footers.
when remove items footer wants stick around @ highest index reached.
there many package level variables don't have access to. think intended usage write entire class in 1 go.
headers , footers better fit layoutmanager anyway, mean, know are, don't need "adapting"
Comments
Post a Comment