Adapter mode is an important design pattern and has been widely used in Android. Adapters are similar to the plugs in the real world, and through adapters we can combine two different types of data that are classified into different classes without having to add or modify the methods in the class according to a need.
The adapter is divided into one-way adapters and two-way adapters, which are used more frequently in Android. A more common way to do this is to first define an adapter class, internally defines a private, matching object that provides a constructor that passes an instance of the object as a parameter, initializes it inside the constructor, and then provides a public method that returns the data type required by another class that needs to be matched. This is done by creating an additional class that is specifically responsible for the conversion of the data type and implements the required functionality without altering the original class. This design pattern provides better reusability and scalability, especially when it is not possible to modify one of the classes or to have more different types of data between classes and classes that need to be adapted.
The common adapter classes in Android are: Baseadapter, simpleadapter, etc.
When I first met Android, I ListView, Gradview in the adapter has been half understand, every time write adapter feel abnormal pain, so have this article, hope to help some beginners.
Take a look at the official explanation of the adapter pattern and convert the interface of a class into another interface that the client wants, and the adapter mode makes it possible for those classes that cannot work together because the interface is incompatible. At first glance certainly unintelligible, the popular saying my personal understanding: when we create a view, certainly must then specify the view the size, the position, the display content information, the touch event callback and so on, we discovered that puts these things together to cause the code to be too coupling or even redundant, This time you can use the adapter mode, separate this process, first we just create a view, as for the view of the content style we do not have to care, to our little brother adapter to do (if this is our younger brother, and our view can be linked), When the little brother completes the task we assigned to him (arranging the style of the child view, parsing the information, the event callback, etc.), we simply steal his work by Setadapter ().
Or more intuitively, we want to buy back a Iphone7, we only need to easily and happily use it to listen to songs, to see movies, talk about micro-letter, as for when he did not power how to do? How to use 110V, 220V voltage charge? How to use the two-hole, three-hole plug? How to fast charge how to slow charge? These do not need our care, to our charger (Adapter) can be, we need to do just connect the USB cable and find the socket (setadapter) on the line.
When you do not know the specific process of adaptation, write adapter is very painful, and then we will lift chestnuts detailed analysis of a complete adapter mode workflow (now In addition to my wonderful company, should no one will use ListView, so here directly to Recyclerview as Li, In fact, ListView's adapter is the same principle).
1. Create a Recyclerview and instantiate it, then wait for our little brother (Adapter) to finish the rest of the physical work.
<android.support.v7.widget.recyclerview
android:layout_width= "match_parent"
android:layout_height= " Wrap_content "
android:id=" @+id/mrecycler "/>
Recyclerview mrecycler= (Recyclerview) Findviewbyid (R.id.mrecycler);
Mrecycler.setlayoutmanager (New Staggeredgridlayoutmanager (2,staggeredgridlayoutmanager.vertical));
2.Adapter use, we first understand the callback cycle of each method from the source.
public static abstract class ADAPTER<VH extends Viewholder> {private final adapterdataobservable mobservable = n
EW adapterdataobservable ();
Public abstract VH Oncreateviewholder (viewgroup parent, int viewtype);
public abstract void Onbindviewholder (VH holder, int position); public void Onbindviewholder (VH holder, int position, list<object> payloads) {Onbindviewholder (holder, position)
; /** * This method is calls {@link #onCreateViewHolder (viewgroup, int)} to create a new * {@link viewholder} and Initi
Alizes some private fields to is used by Recyclerview.
* * @see #onCreateViewHolder (viewgroup, int)/public final VH Createviewholder (viewgroup parent, int viewtype) {
Tracecompat.beginsection (Trace_create_view_tag);
Final VH holder = Oncreateviewholder (parent, ViewType);
Holder.mitemviewtype = ViewType;
Tracecompat.endsection ();
return holder; /** * This method internally the calls {@link #onBindViewHolder (viewholder, int)} to UpdAte the * {@link Viewholder} contents with the item at the given position and also sets up some * private fields to be
Used by Recyclerview. * * @see #onBindViewHolder (viewholder, int) */public final void Bindviewholder (VH holder, int position) {holder.
Mposition = position;
if (Hasstableids ()) {Holder.mitemid = Getitemid (position); } holder.setflags (Viewholder.flag_bound, Viewholder.flag_bound | Viewholder.flag_update | Viewholder.flag_invalid |
Viewholder.flag_adapter_position_unknown);
Tracecompat.beginsection (Trace_bind_view_tag);
Onbindviewholder (holder, Position, holder.getunmodifiedpayloads ());
Holder.clearpayload ();
Tracecompat.endsection ();
/** * Return the view type of the item at <code>position</code> for the purposes * of view recycling. * <p>the default implementation of this method returns 0, making the assumption of * a single view type The adapter. Unlike ListView adapters, types need not * is contiguous.
Consider using ID uniquely identify item view types. * * @param position position to query * @return An integer value identifying the type of the view needed to represent the Item at * <CODE>POSITION</CODE>.
Type codes need not is contiguous.
* * public int getitemviewtype (int position) {return 0;
}/** * Returns The total number of items in the data set hold by the adapter.
* @return The total number of items in this adapter.
* * Public abstract int getitemcount ();
/** * Called when a view created from this adapter has been to a window. * <p>this can be used as a reasonable signal the "view is about to" seen * by the user. If the adapter previously freed any resources in * {@link #onViewDetachedFromWindow (recyclerview.viewholder) Onviewdetac Hedfromwindow} * Those should be restored here.</p> * * @param holder holder of the view being ATTACHed */public void Onviewattachedtowindow (VH holder) {}/** * Called when a view created by this adapter has been
Detached from its window.
* * <p>becoming detached from the ' window is ' not ' necessarily a permanent condition; * The consumer of an Adapter's views could choose to cache views offscreen while they * are not visible, attaching a deta Ching them as appropriate.</p> * * @param holder holder of the view being detached/public void Onviewdetac
Hedfromwindow (VH holder) {}/** * Register a new observer to listen for data changes.
* <p>the Adapter may publish a variety of events describing specific. * Not all adapters could support all change types and some could fall back to a generic * {@link ANDROID.SUPPORT.V7.WIDGET.R Ecyclerview.adapterdataobserver#onchanged () * "Something Changed"} event if more specific data isn't not AVAILABLE.</P&G
T * * <p>components registering observers with a adapter are responsible for * {@link #unregisterAdapterDataObserver (recyclerview.adapterdataobserver) * Unregistering} those observers when F inished.</p> * * @param observer observer to register * @see #unregisterAdapterDataObserver (RECYCLERVIEW.A Dapterdataobserver) */public void Registeradapterdataobserver (Adapterdataobserver observer) {Mobservable.registero
BSERVER (Observer);
}/** * Unregister a observer currently listening for data changes. * * <p>the unregistered observer would no longer receive events about changes * to the adapter.</p> * *
@param observer Observer to unregister * * @see #registerAdapterDataObserver (recyclerview.adapterdataobserver)
public void Unregisteradapterdataobserver (Adapterdataobserver observer) {MOBSERVABLE.UNREGISTEROBSERVER (Observer);
}/** * Called by Recyclerview The It starts observing this Adapter.
* <p> * Keep in mind the same adapter may is observed by multiple recyclerviews. *
* @Param Recyclerview The Recyclerview instance which started observing this adapter.
* @see #onDetachedFromRecyclerView (recyclerview) */public void Onattachedtorecyclerview (Recyclerview recyclerview) {
}/** * Called by Recyclerview The IT stops observing this Adapter.
* * @param recyclerview the Recyclerview instance which stopped observing this adapter.
* @see #onAttachedToRecyclerView (recyclerview) */public void Ondetachedfromrecyclerview (Recyclerview recyclerview) {
}/** * Notify Any registered observers this data set has changed.
* * Public final void notifydatasetchanged () {mobservable.notifychanged ();
}/** * Notify Any registered observers this item at <code>position</code> has changed.
* Equivalent to calling <code>notifyitemchanged (position, NULL); * * <p>this is the item change event and not a structural the Change event. It indicates that all * reflection of the data at <CODE>POSITION</code> is out of the date and should be updated. * The item at <code>position</code> retains the same identity.</p> * * @param position position of T He item that has changed * * @see #notifyItemRangeChanged (int, int)/public final void notifyitemchanged (int posi
tion) {mobservable.notifyitemrangechanged (position, 1); }/** * Notify Any registered observers this item reflected at <code>fromPosition</code> * has been
Moved to <code>toposition</code>. * * <p>this is a structural the Change event. Representations of other existing items in the * data set are still considered up to date and won't be rebound, thoug
H their * positions May altered.</p> * * @param fromposition Previous of the item.
* @param toposition New position of the item. */public final void notifyitemmoved (int fromposition, int toposition) {mobservable.notifyitemmoved (fromposition, top
Osition);
}
}
Adapter is an abstract inner class of recyclerview, we just need to rewrite the various callback methods it exposes (create view, bind view, get data content, notify data changes ...). , you can achieve the purpose of creating and controlling itemview content. Here are some of the overriding methods we use to create adapter:
Oncreateviewholder:
According to the requirements, create a custom style of itemviw, and finally return a viewholder type. Called by the Createviewholder in the adapter inner class.
Based on requirements, create custom style itemviw
@Override public
viewholder oncreateviewholder (viewgroup viewgroup, int viewtype) {
View view = Layoutinflater.from (Viewgroup.getcontext ()). Inflate (r.layout.item,viewgroup,false);
Viewholder VH = new Viewholder (view);
return VH;
}
Onbindviewholder:
The data bean we pass in is bound to the view, which determines how the specific content of our Itemview is presented, called by Bindviewholder in the adapter inner class. You can also handle the callback of the touch event here, as you'll find out later.
The operation that binds the data to the interface
@Override public
void Onbindviewholder (viewholder viewholder, int position) {
ViewHolder.mTextView.setText (Datas[position]);
GetItemCount:
Returns the number of data beans, that is, the number of itemview required.
Gets the number of data
@Override public
int GetItemCount () {return
datas.length;
}
In general, we rewrite the above three methods.
Onviewattachedtowindow Onviewdetachedfromwindow:
Callback when view attachment/Detach window
Registeradapterdataobserver Unregisteradapterdataobserver:
Observer mode primarily for registering and unlocking adapter data
Notifydatasetchanged notifyitemmoved:
By adapter to notify the change of data or item, request to update view.
How do you get adapter to handle the touch events for us? The method of callback through an interface can be done very simply.
First, add an internal interface to our adapter, where the method is implemented when the view is instantiated in the first step.
Public interface Onitemclicklistener {
void Itemclicklistener (View view,int postion);
void Itemlongclicklistener (View view,int postion);
}
Then callback in the Onbindviewholder.
if (mlistener!=null) {//If the listener is set then it is not empty, then the corresponding method
Holder.itemView.setOnClickListener (The new View.onclicklistener ( {
@Override public
void OnClick (View v) {
int pos = holder.getlayoutposition ();//Get the current click item position pos
Mlistener.itemclicklistener (Holder.itemview,pos);//Give the event to the interface that we implement
}
);
Holder.itemView.setOnLongClickListener (New View.onlongclicklistener () {
@Override public
Boolean Onlongclick (View v) {
int pos = holder.getlayoutposition ()//Get the current click item position pos
Mlistener.itemlongclicklistener (Holder.itemview,pos)//Send the event to the interface that we implemented to handle return
true;}
3. Connect Recyclerview with adapter through Setadapter and implement the callback interface within adapter.
Adapter=new Myrecycleradapter (this, list);
Mrecycler.setadapter (adapter);
Adapter.setonclicklistener (New Myrecycleradapter.onitemclicklistener () {
@Override public
Void Itemclicklistener (view view, int postion) {
toast.maketext (Mainactivity.this, "clicked:" +postion, Toast.length_short ). Show ();
@Override public
void Itemlongclicklistener (view view, int postion) {
list.remove (postion);
Adapter.notifyitemremoved (postion);
}
);
So one of the simplest recyclerviewadapter is completed, the end of the paper gives a simple package of their own after the commonrecycleradapter, when used we only need to pass the context, layoutresid,list<t > Data can be.
Thank you for reading, I hope to help you, thank you for your support for this site!