From:https://github.com/etao-open-source/cube-sdk/tree/master/core/src/in/srain/cube/views/list
1. First look at how to use:
@Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview ( R.layout.activity_main); ListView ListView = (ListView) This.findviewbyid (R.id.listview); listviewdataadapter<person> adapter = new listviewdataadapter<person> (null); Adapter.setviewholderclass (NULL, Personviewholder.class, this); Listview.setadapter (adapter); Adapter.Update (Getdatas ());}
The only difference between the use of adapter and the normal ListView is that there is one more step setviewholderclass, the other is no different.
2. Take a look at the specific implementation
(1) Listviewdataadapter.java
public class Listviewdataadapter<t> extends listviewdataadapterbase<t> { protected list<t> Mitemdatalist; Public Listviewdataadapter (list<t> itemdatalist) { update (itemdatalist); } @Override public void Update (list<t> list) { this.mitemdatalist = list; This.notifydatasetchanged (); } Public list<t> getdatalist () { return mitemdatalist; } @Override public int GetCount () { if (mitemdatalist = = null) { return 0; } else{ return mitemdatalist.size (); } } @Override public T getItem (int position) { if (mitemdatalist.size () <= Position | | Position < 0) { re Turn null; } return Mitemdatalist.get (position); } @Override public long getitemid (int position) { return position; }}
It inherits the Listviewdataadapterbase, which is all about data manipulation.
(2) Personviewholder.java
public class Personviewholder extends Viewholderbase<person>{private Context mcontext;private TextView mname; Private ImageView mimg;public Personviewholder (mainactivity context) {This.mcontext = context;} @SuppressLint ("Inflateparams") @Overridepublic view CreateView (Layoutinflater layoutinflater) {View V = Layoutinflater.from (Mcontext). Inflate (R.layout.item, null), Mname = (TextView) V.findviewbyid (r.id.name); mImg = ( ImageView) V.findviewbyid (r.id.image); return v;} @Overridepublic void ShowData (final int position, person ItemData) {Mname.settext (Itemdata.getname ()); Mimg.setimageresource (Itemdata.getresid ()); Mname.setonclicklistener (new View.onclicklistener () {@Overridepublic void OnClick (View v) {toast.maketext (Mcontext, "" +position, Toast.length_short). Show ();}});}}
As you can see, the face is all about the view operation. In this way, a good separation of data and view results, the code becomes more neat and looks pleasing. Later, in writing adapter, only need to write Viewholder can, listviewdataadapter most of the time do not make any changes, need to change the time as long as the inheritance of this class can be, greatly reducing the workload.
See how it's done:
(1) Listviewdataadapterbase:
Public abstract class Listviewdataadapterbase<t> extends Baseadapter {protected viewholdercreator<t> MView Holdercreator; public void Setviewholderclass (Final object enclosinginstance, final class<?> cls, final object ... args) {MV Iewholdercreator = Viewholdercreator.create (enclosinginstance, CLS, args); } @SuppressWarnings ("Unchecked") @Override public View getView (int position, view Convertview, ViewGroup parent) {T ItemData = GetItem (position); Viewholderbase<t> viewholder = null; if (Convertview = = NULL | | (! (Convertview.gettag () instanceof viewholderbase<?>))) {Viewholder = Createviewholder (position); if (Viewholder! = null) {Convertview = Viewholder.createview (Layoutinflater.from (Parent.getcontext ())); if (Convertview! = null) {Convertview.settag (Viewholder); }}} else {ViewholdER = (viewholderbase<t>) convertview.gettag (); } if (Viewholder! = null) {Viewholder.setitemdata (position, convertview); Viewholder.showdata (position, itemdata); } return Convertview; } @Override Public abstract T getItem (int position); public abstract void Update (list<t> List); Private viewholderbase<t> createviewholder (int position) {if (Mviewholdercreator = = null) {throw New RuntimeException ("View holder creator is null"); } if (Mviewholdercreator! = null) {return mviewholdercreator.createviewholder (position); } return null; }}
In this we see that it inherits the Baseadapter, in addition to rewriting the GetView, there are two additional methods: Setviewholderclass () and Createviewholder (); Setviewholderclass is the method that the client invokes, it will create a viewholdercreator,viewholdercreator to create the Viewholder. When the ListView calls GetView (), if Convertview is empty, Createviewholder () is used to create the Viewholder and then viewholder to create the view. If Convertview is not empty, reset the data and position and return the Convertview.
(2) Viewholdercreator.java:
public class Viewholdercreator<t> {private final constructor<?> mconstructor; Private object[] minstanceobjects; Private Viewholdercreator (constructor<?> Constructor, object[] instanceobjects) {mconstructor = Constructor; Minstanceobjects = instanceobjects; } public static <T> viewholdercreator<t> Create (Final Object enclosinginstance, final class<?> cls, F Inal Object ... args) {if (CLS = = null) {throw new IllegalArgumentException ("Viewholderclass is null.") ); }//Top class Boolean isenclosinginstanceclass = FALSE; if (Cls.getenclosingclass ()! = NULL &&! Modifier.isstatic (Cls.getmodifiers ())) {Isenclosinginstanceclass = true; }//Inner instance class should pass enclosing class, so +1 int argslen = Isenclosinginstanceclass? Args.length + 1:args.length; Final object[] instanceobjects = new Object[argslen]; int CopystArt = 0; If it is a inner instance class, first argument should be the enclosing class instance if (Isenclosinginstanceclas s) {instanceobjects[0] = enclosinginstance; Copystart = 1; }//has copy construction parameters if (Args.length > 0) {system.arraycopy (args, 0, Instanc Eobjects, Copystart, args.length); }//Fill the types final class<?>[] parametertypes = new Class[argslen]; for (int i = 0; i < instanceobjects.length; i++) {Parametertypes[i] = Instanceobjects[i].getclass (); } constructor<?> Constructor = null; try {constructor = Cls.getdeclaredconstructor (parametertypes); } catch (Nosuchmethodexception e) {e.printstacktrace (); } if (constructor = = null) {throw new IllegalArgumentException ("Viewholderclass can not is initiated"); } return new viewholdercreator<T> (constructor, instanceobjects); } @SuppressWarnings ("Unchecked") public viewholderbase<t> createviewholder (int position) {Object object = Null try {Boolean isaccessible = Mconstructor.isaccessible (); if (!isaccessible) {mconstructor.setaccessible (true); } object = Mconstructor.newinstance (minstanceobjects); if (!isaccessible) {mconstructor.setaccessible (false); }} catch (Exception ex) {ex.printstacktrace (); } if (object = = NULL | |! ( Object instanceof Viewholderbase) {throw new IllegalArgumentException ("Viewholderclass can not is initiated") ; } return (viewholderbase<t>) object; }}
The Create () method is to use reflection to obtain the constructors and parameters used to create Viewholder, and createviewholder () reflection constructs Viewholder.
(3) Viewholderbase.java
Public abstract class Viewholderbase<t> { protected int mposition =-1; protected View Mcurrentview; public void SetItemData (int position, view view) { mposition = position; Mcurrentview = view; } /** * Create a view from resource an Xml file, and hold the view, is used in displaying data. * /public abstract View CreateView (Layoutinflater layoutinflater); /** * Using the held views to display data * /public abstract void ShowData (int position, T itemdata);} This method is very convenient to use, its core is to use reflection to create Viewholder, the downside of the reflection is the type of parameter is very strict, but his flaws, is very practical. PS: This is also an open source implementation seen from GitHub, <a target=_blank href= "Https://github.com/etao-open-source/cube-sdk/tree/master/core /src/in/srain/cube/views/list ">https://github.com/etao-open-source/cube-sdk/tree/master/core/src/in/srain/ Cube/views/list</a>
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Android-a simple package for the adapter of a ListView