So with the ListView, the GridView Why do you need recyclerview such a control? The Recyclerview architecture as a whole provides a pluggable experience, highly decoupled, unusually flexible, and itemanimator achieve stunning results by setting the different layoutmanager,itemdecoration it offers.
You want to control how it is displayed, please layoutmanager through the layout manager
You want to control the interval between the item (can be drawn), please pass Itemdecoration
You want to control the animation of item additions and deletions, please pass Itemanimator
You want to control clicks, long press events, please write yourself (rub, this is a NI. )
The layout of each item is as follows:
<?xml version= "1.0" encoding= "Utf-8"?>
<linearlayout xmlns:android= "Http://schemas.android.com/apk/res/android"
Android:id= "@+id/recycler_view_test_item_person_view"
android:orientation= "Vertical"
Android:layout_width= "Match_parent"
android:layout_height= "Wrap_content"
Android:padding= "15DP"
Android:background= "#aabbcc"
>
<textview
Android:id= "@+id/recycler_view_test_item_person_name_tv"
Android:layout_width= "Match_parent"
android:layout_height= "Wrap_content"
Android:textsize= "18SP"
Android:background= "#ccbbaa"
/>
<textview
Android:id= "@+id/recycler_view_test_item_person_age_tv"
Android:layout_width= "Match_parent"
android:layout_height= "Wrap_content"
android:paddingleft= "5DP"
Android:background= "#aaccbb"
Android:textsize= "15SP"
/>
</LinearLayout>
The item's layout is simple, with only two TextView, one to display the name, and one to display the age.
The entity class for person does not have code, two attributes: Name and age.
Then you need to use the Recyclerview, so you need to add support V7 to class path and add the control to the layout:
<android.support.v7.widget.recyclerview
Android:id= "@+id/recycler_view_test_rv"
android:scrollbars= "Vertical"
Android:layout_width= "Match_parent"
android:layout_height= "Match_parent"
Android:background= "#bbccaa"
/>
And then in the OnCreate:
1 recyclerview.sethasfixedsize (TRUE);
2
3 Recyclerview.layoutmanager LayoutManager = new Linearlayoutmanager (context);
4 Recyclerview.setlayoutmanager (LayoutManager);
5
6 InitData ();
7 adapter = new Personadapter (personlist);
8 Adapter.setonrecyclerviewlistener (this);
9 Recyclerview.setadapter (adapter);
such as the above code:
Line1: Keeps the recyclerview in a fixed size, which can improve the performance of Recyclerview.
Line3:linearlayoutmanager, if you need to display a scrolling list or a vertical scrolling list, use this layoutmanager. Obviously, we want to achieve the effect of ListView, so we need to use it. After this linearlayoutmanager is generated, you can set the direction of his scrolling, the default vertical scrolling, so there is no explicit setting.
Line6: Initializes the data source.
Line7~9: Like ListView, you need to set up the Recyclerview adapter, but the adapter here is not the same as the ListView adapter use, The Adapter here need to inherit recyclerview.adapter, and you need to implement 3 methods:
-Oncreateviewholder ()
-Onbindviewholder ()
-GetItemCount ()
Look directly at the code:
1 package Com.wangjie.helloandroid.sample.recycler.person;
2
3 Import Android.support.v7.widget.RecyclerView;
4 Import Android.view.LayoutInflater;
5 Import Android.view.View;
6 Import Android.view.ViewGroup;
7 Import Android.widget.LinearLayout;
8 Import Android.widget.TextView;
9 Import Com.wangjie.androidbucket.log.Logger;
Import COM.WANGJIE.HELLOANDROID.R;
11
Import java.util.List;
13
14/**
* Author:wangjie
* email:tiantian.china.2@gmail.com
* DATE:1/17/15.
18 */
public class Personadapter extends Recyclerview.adapter {
public static interface Onrecyclerviewlistener {
void Onitemclick (int position);
Boolean onitemlongclick (int position);
23}
24
Onrecyclerviewlistener private Onrecyclerviewlistener;
26
The public void Setonrecyclerviewlistener (Onrecyclerviewlistener onrecyclerviewlistener) {
This.onrecyclerviewlistener = Onrecyclerviewlistener;
29}
30
To private static final String TAG = PersonAdapter.class.getSimpleName ();
List<person> private List;
33
Personadapter Public (list<person> List) {
This.list = list;
36}
37
@Override
Recyclerview.viewholder Oncreateviewholder (viewgroup viewgroup, int i) {
LOGGER.D (TAG, "Oncreateviewholder, I:" + i);
View view = Layoutinflater.from (Viewgroup.getcontext ()). Inflate (R.layout.recycler_view_test_item_person, NULL);
Linearlayout.layoutparams LP = new Linearlayout.layoutparams (ViewGroup.LayoutParams.MATCH_PARENT, Viewgroup.lay Outparams.wrap_content);
VIEW.SETLAYOUTPARAMS (LP);
Return to New Personviewholder (view);
45}
46
@Override
public void Onbindviewholder (Recyclerview.viewholder viewholder, int i) {
LOGGER.D (TAG, "Onbindviewholder, I:" + i + ", Viewholder:" + viewholder);
Personviewholder holder = (personviewholder) Viewholder;
Wuyi holder.position = i;
Person of person = list.get (i);
Holder.nameTv.setText (Person.getname ());
Holder.ageTv.setText (Person.getage () + "old");
55}
56
@Override
GetItemCount public int () {
List.size return ();
60}
61
The class Personviewholder extends Recyclerview.viewholder implements View.onclicklistener, View.onlongclicklistener
63 {
The public View Rootview;
TextView public Nametv;
The public TextView Agetv;
public int position;
68
Public Personviewholder (View Itemview) {
Super (Itemview);
Nametv = (TextView) Itemview.findviewbyid (R.ID.RECYCLER_VIEW_TEST_ITEM_PERSON_NAME_TV);
Agetv = (TextView) Itemview.findviewbyid (R.ID.RECYCLER_VIEW_TEST_ITEM_PERSON_AGE_TV);
Rootview = Itemview.findviewbyid (R.id.recycler_view_test_item_person_view);
Rootview.setonclicklistener (this);
Rootview.setonlongclicklistener (this);
76}
77
@Override
The-public void OnClick (View v) {
if (null!= onrecyclerviewlistener) {
Bayi Onrecyclerviewlistener.onitemclick (position);
82}
83}
84
@Override
public boolean Onlongclick (View v) {
if (null!= onrecyclerviewlistener) {
The return Onrecyclerviewlistener.onitemlongclick (position);
89}
return false;
91}
92}
93
94}
As shown in the code above:
Public Recyclerview.viewholder Oncreateviewholder (viewgroup viewgroup, int i)
This method is primarily born into a view for each item inflater, but the method returns a Viewholder. The approach is to encapsulate the view directly in the Viewholder, and then we're looking at the Viewholder example, and of course this viewholder needs to be written by ourselves. The tedious steps of the original Convertview.settag (holder) and Convertview.gettag () were omitted directly.
public void Onbindviewholder (Recyclerview.viewholder viewholder, int i)
This method is mainly used for matching rendering data into view. Method provides you with a viewholder instead of the original Convertview.
In contrast, the previous wording is clear:
1 @Override
2 public View GetView (int position, View Convertview, ViewGroup parent) {
3 Viewholder Holder;
4 if (null = = Convertview) {
5 Holder = new Viewholder ();
6 Layoutinflater Minflater = (layoutinflater) context.getsystemservice (Context.layout_inflater_service);
7 Convertview = minflater.inflate (R.layout.item, NULL);
8 holder.btn = (Button) Convertview.findviewbyid (R.ID.BTN);
9 holder.tv = (TextView) Convertview.findviewbyid (r.id.tv);
HOLDER.IV = (TextView) Convertview.findviewbyid (R.ID.IV);
11
Convertview.settag (holder);
}else{
Holder = (viewholder) convertview.gettag ();
15}
Final hashmap<string, object> map = list.get (position);
17
Holder.iv.setImageResource (Map.get ("IV"). ToString ()) (integer.valueof);
Holder.tv.setText (Map.get ("TV"). toString ());
20
Holder.btn.setOnClickListener (New View.onclicklistener () {
@Override
public void OnClick (View v) {
Toast.maketext (Context, Map.get ("btn"). ToString (), Toast.length_short). Show ();
25}
26});
27
return convertview;
29}
30
Class viewholder{
Button btn;
ImageView IV;
TextView TV;
35
36}
The comparison can be found:
In the old writing, the line5~line12+line28 part of the code actually plays a role equivalent to the new Oncreateviewholder ();
In the old writing, the line14~line26 part of the code actually plays a role equivalent to the new Onbindviewholder ();
Since this is the case, then we can move the corresponding code to the corresponding Oncreateviewholder () and Onbindviewholder () two methods.
Because Recyclerview helped us encapsulate the holder, So we write our own viewholder need to inherit Recyclerview.viewholder, only in this way, Recyclerview can help you to manage this viewholder class.
Since the code for the rendering data portion of the GetView method is equivalent to Onbindviewholder (), if the Adapter.notifydatasetchanged () method is invoked, the Onbindviewholder () should also be called again. Method, right? After the experiment, sure enough!
In addition to the adapter.notifydatasetchanged () method, the new adapter also provides other methods, as follows:
Public final void notifydatasetchanged ()
Public final void notifyitemchanged (int position)
Public final void notifyitemrangechanged (int positionstart, int itemCount)
Public final void notifyiteminserted (int position)
Public final void notifyitemmoved (int fromposition, int toposition)
Public final void notifyitemrangeinserted (int positionstart, int itemCount)
Public final void notifyitemremoved (int position)
Public final void notifyitemrangeremoved (int positionstart, int itemCount)
Basically see the name of the method to know what this method is doing,
The first method has nothing to say, as before.
notifyitemchanged (int position), position data has changed, that calls this method, it will callback corresponding position Onbindviewholder () method, of course, Because Viewholder is reused, if the position is outside the current screen, it will not be recalled, because there is no sense, the next time the position scroll will be within the current screen will also invoke the Onbindviewholder () method to refresh the data. The same is true of other methods.
Public final void notifyitemrangechanged (int positionstart, int itemCount), as the name suggests, You can refresh the number of item ItemCount starting from Positionstart (here The refresh refers to the callback Onbindviewholder () method).
Public final void notifyiteminserted (int position), which can be refreshed using this method when the position position is inserted into a piece of data, note that this method invocation will have an inserted animation. This animation can be used by default, or it can be defined by itself.
Public final void notifyitemmoved (int fromposition, int toposition), this method can be used to refresh when moving from Fromposition to Toposition
Public final void notifyitemrangeinserted (int positionstart, int itemCount) is clearly bulk added.
Public final void notifyitemremoved (int position), which is refreshed when position is deleted, also has animations.
Public final void notifyitemrangeremoved (int positionstart, int itemCount), bulk deletion.
After the analysis of these methods, we will implement a click a button, add a data, long press an item, delete a piece of data scene.
Here's the code for a new piece of data:
1 person who = new person (i, "wangjie_" + I, + i);
2 adapter.notifyiteminserted (2);
3 Personlist.add (2, person);
4 adapter.notifyitemrangechanged (2, Adapter.getitemcount ());
As above code:
Line2: Indicates where the position is 2, inserts a piece of data, this time the animation begins to execute.
Line3: Represents a new piece of data in the data source where position is 2 (in fact, this is the real new data).
Line4: Why do you want to refresh the data after position is 2? Because, after inserting a data in the position of position 2, the position of the new data becomes 2, the original position 2 should become 4, so the position of all the data after 2 has changed, So we need to refresh the data after Position2. This is theoretically true, but the number of refreshes is only position on the screen after 2 of the data. If you use Notifydatasetchanged () here to refresh all the item displayed on the screen, can you? The results will not go wrong, but there is a problem, the previous call to the Notifyiteminserted () method will be executed after the animation, if you call notifydatasetchanged () Refresh all the item displayed on the screen, The item that is currently executing the animation must also be refreshed so that the result is that the previous animation is not finished, it is immediately refreshed, and the animation is not visible. So just refresh 2 after the item is OK.
Look at the Recyclerview API, found no setonitemclicklistener--, so or their own onitemclick from the adapter of the callback out of it. This is very simple, just like Onrecyclerviewlistener in the personadaper above.
Long press the deletion code as follows:
1 adapter.notifyitemremoved (position);
2 Personlist.remove (position);
3 adapter.notifyitemrangechanged (position, Adapter.getitemcount ());
The code is basically consistent with the code you inserted earlier. First notify the animation, then delete the data from the data source, and then notify the position after the data refresh is OK.
So the ListView effect is realized.
The advent of recycleview convenient for us to customize the appropriate layout, a few lines of code can transform a variety of state--listview, GridView, waterfall flow, and so on, the following is a brief description of how to write adapter related code
Import Android.content.Context;
Import Android.support.v7.widget.RecyclerView;
Import Android.view.LayoutInflater;
Import Android.view.View;
Import Android.view.ViewGroup;
Import Android.widget.ImageView;
Import Android.widget.LinearLayout;
Import Android.widget.ListAdapter;
Import Android.widget.ListView;
Import Android.widget.TextView;
Import Com.squareup.picasso.Picasso;
Import java.util.List;
/**
* Created by Abel on 16/4/21.
*/
public class Recycleviewadapter extends Recyclerview.adapter<recycleviewadapter.myholder> {
Private Layoutinflater Minflater;
Private list<collectionentity> List;
private context;
Onitemclicklistener Onitemclicklistener;
/*
Get Data source
*/
Public Recycleviewadapter (context context, list<collectionentity> List) {
This.minflater = Layoutinflater.from (context);
This.list = list;
This.context = context;
}
/*
Load Item Layout
*/
@Override
Public Myholder Oncreateviewholder (viewgroup parent, int viewtype) {
Myholder Myholder = new Myholder (Minflater.inflate (r.layout.item_collection, parent, false));
return myholder;
}
/**
* Binding Data
* @param holder Item
* @param position position
*/
@Override
public void Onbindviewholder (final myholder holder, int position) {
Collectionentity collectionentity = list.get (position);
Holder.tv_already_pay.setText ("Sold" + spannablestringutil.checknull (1, Collectionentity.getalreadypay ()));
Holder.tv_newMoney.setText ("¥" + spannablestringutil.checknull (1, Collectionentity.getnewmoney ()));
Holder.tv_oldMoney.setText (Spannablestringutil.adddeletelinespantwo ("¥" + spannablestringutil.checknull) (1, Collectionentity.getoldmoney ()));
if (collectionentity.getpic ()!= null) {
Picasso.with (context). Load (Url.imagr_root + collectionentity.getpic ())
. Tag ("Bitmap")
. Placeholder (r.mipmap.pic_common_carlogo_loading)
. into (Holder.userpic);
}
if (Onitemclicklistener!= null) {
if (!holder.itemview.hasonclicklisteners ()) {
Holder.itemView.setOnClickListener (New View.onclicklistener () {
@Override
public void OnClick (View v) {
Onitemclicklistener.onitemclick (V, holder.getadapterposition ());
}
});
}
}
}
@Override
public int GetItemCount () {
return List.size ();
}
/**
* Click on event interface
*/
Public interface Onitemclicklistener {
void Onitemclick (view view, int postion);
}
public void Setonitemclicklistener (Onitemclicklistener onitemclicklistener) {
This.onitemclicklistener = Onitemclicklistener;
}
/**
* Viewholder
*/
public class Myholder extends Recyclerview.viewholder {
Private ImageView userpic;
Private TextView Tv_title, Tv_newmoney, Tv_oldmoney, Tv_already_pay;
Private LinearLayout Ll_root;
Public Myholder (View Itemview) {
Super (Itemview);
Userpic = (ImageView) Itemview.findviewbyid (r.id.img_userpic);
Tv_title = (TextView) Itemview.findviewbyid (r.id.tv_collection_title);
Tv_newmoney = (TextView) Itemview.findviewbyid (R.id.tv_now_price);
Tv_already_pay = (TextView) Itemview.findviewbyid (R.id.tv_already_sell);
Ll_root = (linearlayout) Itemview.findviewbyid (r.id.ll_root);
Tv_oldmoney = (TextView) Itemview.findviewbyid (R.id.tv_old_price);
}
}
}
Since Recycleview does not provide click event monitoring, we need to implement it ourselves, the above interface is an externally released click event, which needs to be added in the activity
Mrecyview.setlayoutmanager (This) (new Linearlayoutmanager);
To set the manager to achieve the ListView and GridView Effect