First of all, praise the great God of Hyman
Once simply rewrite a baseadapter to keep the GetView method abstract. And Viewholder is not abstract.
。。
Viewholder (with a collection + generic management access view)
/** * author:stone * Email: [email protected] * time:15/7/24 */public class Stoneviewholder {privat e int mposition; Private View Mconvertview; Private sparsearray<view> mviews; Manage view public Stoneviewholder in Listview-item (context context, int layoutid, int position, ViewGroup parent) { This.mposition = position; This.mconvertview = Layoutinflater.from (context). Inflate (LayoutID, parent, false); This.mConvertView.setTag (this); This.mviews = new sparsearray<view> (); Public View Getconvertview () {return mconvertview; } public static Stoneviewholder getinstance (context context, int layoutid, int position, View Convertview, V Iewgroup parent) {if (Convertview = = null) {return new Stoneviewholder (context, LayoutID, position, PA Rent); } else {Stoneviewholder holder = (stoneviewholder) convertview.gettag (); Holder.mposition = position; MorePosition return holder in the newly reused Convertview; }} public <t extends view> T getView (int viewId) {View view = Mviews.get (viewId); if (view = = null) {view = Mconvertview.findviewbyid (viewId); Mviews.put (viewId, view); } return (T) view; } public <T> void Settag (int viewId, T tag) {GetView (viewId). Settag (tag); } public <T> T gettag (int viewId) {return (T) GetView (VIEWID). Gettag (); }/*------------------------Set the View property (extended later)--------------------------------*/public stoneviewholder setText (int v Iewid, String text) {((TextView) GetView (viewId)). SetText (text); return this; } public stoneviewholder SetText (int viewId, int resId) {//r.string. ((TextView) GetView (viewId)). SetText (ResId); return this; } public stoneviewholder Setimagebitmap (int viewId, Bitmap Bitmap) {(ImageView) GetView (viewId)). Setimagebitmap (bitmap); return this; The public stoneviewholder setimageresource (int viewId, int resId) {(ImageView) GetView (viewId)). Setimageresource (RESID); return this; }}
Adapter
/** * author:stone * Email: [email protected] * time:15/7/24 + */public abstract class STONELISTADAPTER&L T T> extends Baseadapter {private list<t> mdata; Private Context Mcontext; private int mlayoutid; Public Stonelistadapter (context context, int layoutid, list<t> data) {This.mcontext = context; This.mlayoutid = LayoutID; This.mdata = data = = null? New Arraylist<t> (): data; } @Override public int getcount () {return mdata.size (); } @Override public T getItem (int position) {return mdata.get (position); } @Override public long getitemid (int position) {return position; } @Override public View getView (int position, view Convertview, ViewGroup parent) {Stoneviewholder Holder = Stoneviewholder.getinstance (Mcontext, Mlayoutid, Position, Convertview, parent); GetView (Mcontext, holder, position); Return Holder.getconvertview (); } protected abstract void GetView (context context, stoneviewholder holder, int position);}
Use in Listviewactivity
Stonebaseadapter = new Stonelistadapter<user> (Listviewactivity.this, R.layout.activity_listview_item, MData) { @Override protected void GetView (context context, final Stoneviewholder holder, final int position) { User u Ser = GetItem (position); Holder.settext (r.id.tv_id, User.getid ()). SetText (R.id.tv_name, User.getname ()) . SetText (R.id.tv_age, User.getage () + ""); Holder.getview (r.id.btn_test). Setonclicklistener (New View.onclicklistener () { @Override public Void OnClick (View v) { }} );} ;
about Adapter View grab Focus :
Suppose Listview.setonitemclicklistener (listener); and the Button.setonclicklistener (listener) in item;
No matter how you click, the button will always be triggered ...
Just add a property to the Root-layout of item: android:descendantfocusability= "Blocksdescendants"
About Item-view after reuse. Show Clutter:
Sometimes there are too many entries to swipe to the next screen of data. Some view re-uses the state of the view (for example, the selection status of a checkbox. ImageView's pictures appear repeatedly) can become chaotic.
General treatment. There needs to be a mechanism to manage a corresponding relationship: What is the state of the current position
Let's say the checkbox checks for state confusion:
Class Myadapter extends Stonelistadapter<user> {private Sparsebooleanarray mcheckstatearray; Public Myadapter (context context, int layoutid, List data) {Super (context, layoutid, data); This.mcheckstatearray = new Sparsebooleanarray (); } public void setchecked (int position, Boolean isChecked) {mcheckstatearray.put (position, isChecked); } public boolean isChecked (int position) {return mcheckstatearray.get (position); } @Override protected void GetView (context context, final Stoneviewholder holder, final int position) { CheckBox cb = Holder.getview (R.id.cb_check); Cb.setoncheckedchangelistener (New Compoundbutton.oncheckedchangelistener () {@Override publi c void OnCheckedChanged (Compoundbutton buttonview, Boolean isChecked) {setchecked (position, isChecked) ;//Record status. Anti-cache Display} }); Cb.setchecked (isChecked (position)); } }
About Sparsearray
Sparsearray internal implementations are array arrays. When the length is insufficient, the system.arraycopy is called
There are two arrays of keys and values inside.
Put (key, value); Binary find where key should be stored because key is an integer type
Put, get when both arrays are data at the same location as the operation
Sparsearray for alternative shapes such as Hashmap<integer, object>
Sparsebooleanarray for alternative shapes such as Hashmap<integer, boolean>
Sparseintarray for alternative shapes such as Hashmap<integer, integer>
Sparselongarray for alternative shapes such as Hashmap<integer, long>
Support.v4.util.SparseArrayCompat provides the Sparsearray implementation of the V4 package corresponding platform
Android Baseadapter and Viewholder optimized to solve ListView item grab focus issues and item confusion issues