Deep analysis of Recyclerview components in Android _android

Source: Internet
Author: User
Tags gettext stub

Some days ago, in order to implement the animation effect based on ListView in the current Android program, I wanted to introduce the newest recyclerview into the program, so I took some time to study the basic situation of Recyclerview. This article is a summary of what is known in these days.

On the internet about the basic use of Recyclerview has been more detailed introduction, and its design structure is similar to ListView, so this article will not focus on how to use, in the end of the reference can be related content. This is mainly to introduce the basic functions of recyclerview, design concepts, and the system provides the API.

What is Recyclerview
Recyclerview is a new ViewGroup added to the Android L (aka later Lollipop). But since it's added to the Android system as a support-v7 library, it's not just a lollipop version of Android that can be used, as long as the library is introduced into a development project and used at any API level. But looking at its documentation, you can feel the Recyclerview is so strong "still in perfect" feeling, because the introduction of it only a short sentence:

A flexible view for providing a limited windows into a large data set.

Read this sentence, in fact, has been often used ListView and the GridView is basically satisfied with this description. And from the single rendering effect to see Recyclerview and ListView, the GridView is not the most difference.

But its "flexible" does not simply mean that it can switch between the ListView and the GridView arbitrarily, but that it can create more complex, scrollable views, such as horizontal ListView, or a popular waterfall-streaming layout on the Web ( Masonry). But most of the layout systems are not available and must be implemented by the developer themselves.

So Recyclerview's "flexible": anything can be done, but do everything yourself.

The main differences between Recyclerview and ListView
as long as the Lieanerlayoutmanager provided with Android and the vertical mode, Recyclerview can achieve the ListView's basic effect perfectly. The design structure of both is the way in which the data (dataset) is detached from the view and then connected through the adapter (Adapter).

But Recyclerview has the following major improvements relative to ListView:

Enforcing the use of Viewholder
in ListView Performance optimization, Android recommends using Viewholder to reduce the use of Findviewbyid () to improve efficiency. However, the viewholder,android on ListView is only recommended, not mandatory. However, because the use of Viewholder mode is very meaningful, so in the Recyclerview Viewholder become a must use the pattern, adapter asked to return from the normal view into the Viewholder. However, if the implementation is not a custom view of some of the actual variables, Viewholder also lost its significance.

No Onitemclicklistener.
ListView from its parent class Adapterview directly inherits the response of a subproject click, the developer can define its own onitemclicklistner to accept the Click event. But this design also poses some problems, such as the child's internal view if the Onclicklistener is set, then the subproject view itself is not known, which may cause the view-click state to not sync. Reyclerview does not provide a simple response to the child item being clicked on the listener, although it has a onitemtouchlistener, but in this interface method there is no information about the item being clicked, the interface is just to help the developer intercept the touch event, and for how to handle it, Detects that a touched object is left to the developer to complete

View and layout separation
ListView Do the data and view separation, Recyclerview in the view and layout of further separation between, so there is layoutmanager. Recyclerview is responsible for managing the reuse of views, and then give the layout to the LayoutManager, through configuration or switching LayoutManager can achieve different layout effects. Unlike ListView is limited to vertical scrolling layouts. At the same time, Recyclerview also provides itemdecoration, and additional views can be added on the basis of existing child views. For example, to do a split line, in the ListView need to occupy an additional viewtype to provide the view, now you do not need to add to the adapter in the actual logical business-related ancillary content.

Animate effects that support sub-project hierarchies
ListView can also support the animation effects at the subproject level, and there are a lot of introductions in the Devbytes channel on the Android developers, but after seeing its implementation you'll find out how ugly and tedious the solution is. Most of the time, the position state of the child view is computed and parsed. Recyclerview brings a very concise itemanimator interface. When the data in the adapter occurs "additions and deletions Change", the animation can be activated by invoking the adapter corresponding method. Of course, developers also need to implement specific Itemanimator objects to achieve the desired animation effect, but its clear structure and interface has been greatly improved than ListView.

The present situation of Recyclerview
the above mentioned Recyclerview Suite has been added to the Deluxe Support library V7, and is placed in a separate library, so as long as the Android The dependencies of the Gradle compiled file for the studio project adds the following sentence to start using the Recyclerview:

Compile ' com.android.support:recyclerview-v7:21.0.+ '
However, see the library provided by the implementation of their own objects, reflecting the basic operating procedures, you will find that Recyclerview can do looks a lot, but has done too little.

Recyclerview.adapter

Recyclerview provides an abstract adapter class, and then it's gone. There are no subclasses that can be used directly, arrayadapter like ListAdapter, and simplecursoradapter ready-made classes. Everything is left to the developer to implement the definition.

It's pretty normal to think about it, but it should be very rare to use arrayadapter in real products because most lists are not simple lines of text. The use of CursorAdapter also tends to implement different inheritance classes to provide child views. Moreover Recyclerview adapter and ListAdapter in the idea is still the same, so want to realize a recyclerviewcursoradapter, directly from the CursorAdapter material can be.

It is also noteworthy that the adapter of Recyclerview is relatively listadapter on the interface.

First, it splits the GetView () method into Createviewholder () and Bindviewholder () two. But there is nothing to be nervous about, in the CursorAdapter has seen this more reasonable design. The return object is also changed from view to Viewholder just mention.

The key point to note is that Createviewholder (viewgroup parent, int viewtype) The second parameter, although it is shaping, is not the position of the current subkey (position), but rather the invocation of Getitemviewtype () The category of the subkey that was obtained. It seems that when creating a viewholder, Recyclerview intentionally hides the details of the subkey, hoping that the developer relies solely on its category to create the corresponding view and Viewholder.

Second, Recyclerview's adapter has the same notifydatasetchanged () method as ListAdapter, and there is a stack of notification data changes that triggers animation effects:

    • final void notifyitemchanged (int position);
    • final void notifyiteminserted (int position);
    • final void notifyitemmoved (int fromposition, int toposition);
    • final void notifyitemrangechanged (int positionstart, int itemCount);
    • final void notifyitemrangeinserted (int positionstart, int itemCount);
    • final void notifyitemrangeremoved (int positionstart, int itemCount);
    • final void notifyitemremoved (int position);

Calling these methods triggers the corresponding method on the itemanimator that is used to produce the animation.

Recyclerview.viewholder

In the ListView era, in fact already in use Viewholder, just then the method looks more flattering, to hide in the view of the tag. Now Recyclerview enforces the use of Viewholder, and Viewholder, in addition to the references to the child view, there are information such as itemviewtype and position.

Recyclerview.layoutmanager

LayoutManager is a new section relative to ListView, by inheriting the class to implement a custom layout, unlike ListView, which only has a fixed layout. The support library provides two out-of-the-box subclasses: Linearlayoutmanager and Staggeredgridlayoutmanager. The former can get the same layout as ListView, and it can be horizontal, while the latter provides a layout like the GridView. So the basic routines in the application can be met.

If you need to implement custom LayoutManager, it's more cumbersome to understand recycle, scrap, dirty concepts about subproject view state. I have not yet tried to create a custom layoutmanager, but there is a section in the reference document at the end of this article that describes how to implement.

Recyclerview.itemanimator

Implementing Itemanimator by implementing inheritance, and then creating object settings to Recyclerview can result in animated animations based on subprojects. However, there is no detailed description guide for how to properly create a itemanimator subclass.

Look at the only subclass of Defaultitemanimator available in the library, and you can see that its animation effect is a simple alpha gradient. It is also found that the implementation is so complex, there are many operations on the animation steps, but also note that the animation is interrupted in the middle of the processing, at the end of the view to reset the state for reuse. This, in turn, shows that Itemanimator basically does not provide any information on how to implement and manage animations. On the other hand, because the implementation of defaultitemanimator is too specific, it is not appropriate as a custom Itemanimator parent class.

It is believed that when more and more recyclerview are applied to the program, more reasonable design of this aspect will be put forward. At present on the GitHub also has a lot of reference to the implementation of defaultitemanimator, such as this, and this.

With regard to the use of itemanimator, there are several caveats: if Itemanimator,recyclerview is not provided, the default will create a defaultitemanimator for animation, So you don't need to display the Defaultitemanimator object to the Recyclerview; Add (add) and delete (remove) are the default, but modify (change) Effect requires calling Setsupportschangeanimations (Boolean) to specify whether it is enabled, and the default is to animate without modification.

Overall, the Recyclerview is very powerful and its structural design is very open, which also makes it more difficult to use. As more and more people begin to try to use this part, there will be more and more profound understanding and design implementation. In addition, reading the source code of Recyclerview can help to understand its design ideas, in the future design of other reusable view can have a better reference.

DEMO

Having said so much, let's take a look at a recyclerview implementation of the Picture Text button in the mixed row demo:

First of all, let's look at my engineering structure.

First of all, stick out my main_acitivy.xml.

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android=
"http://schemas.android.com/apk/" Res/android "
 android:layout_width=" match_parent "
 android:layout_height=" match_parent "
 android:o" rientation= "Vertical" >

 <!--A Recyclerview with some commonly used attributes-->
< Android.support.v7.widget.RecyclerView
 android:id= "@+id/my_recycler_view"
 android:scrollbars= "vertical "
 android:layout_width=" match_parent "
 android:layout_height=" match_parent "/>
</ Linearlayout>

A few other XML will not be posted, very simple to write textview,imgeview and so on.

And then we'll look at the code, first of all, the code inside the bean.

Package com.androidl.bob;

public class Bean {public
 static final int y_type = 0;//view type 0 public
 static final int x_type = 1;//view type 2
   public static final int z_type = 2;//view Type 3
 private int type;
 private String text;

 public Bean (int type, String text) {
  super ();
  This.type = type;
  This.text = text;

 public int GetType () {return
  type;
 }

 public void SetType (int type) {
  this.type = type;
 }

 Public String GetText () {return
  text;
 }

 public void SetText (String text) {
  this.text = text;
 }

}

And then the code inside the adapter:

Package com.androidl.bob;

Import java.util.List;

Import COM.EXAMPLE.ANDROIDL.R;
Import Android.support.v7.widget.RecyclerView;
Import Android.support.v7.widget.RecyclerView.ViewHolder;
Import Android.view.LayoutInflater;
Import Android.view.View;
Import Android.view.ViewGroup;
Import Android.widget.Button;
Import Android.widget.ImageButton;
Import Android.widget.ImageView;
Import Android.widget.TextView;

Import Android.widget.Toast; /** * DATE:2014/7/15 * * * @author Edsheng * */public class Recycleadapter extends Recyclerview.adapter<viewhol

 der> {private list<bean> beans;
  Public recycleadapter (list<bean> beans) {super ();
 This.beans = beans; /** * Internal Textholer * * * @author Edsheng * */public class Textholer extends Recyclerview.viewholder {pub

  Lic TextView TextView;
   Public Textholer (View TextView) {super (TextView);
  This.textview = (TextView) Textview.findviewbyid (R.id.mytext); }/** * Iamgeholder * * @aUthor Edsheng * */public class Imageholer extends Recyclerview.viewholder {public ImageView ImageView;
   Public Imageholer (View TextView) {super (TextView); This.
  ImageView = (ImageView) Textview.findviewbyid (R.ID.MYIAMGE);
  }/** * Button holder * * * @author Edsheng */public class Buttonholder extends Recyclerview.viewholder {

  Public button button;
   Public Buttonholder (View TextView) {super (TextView);
  This.button = (Button) Textview.findviewbyid (R.id.mybutton);
 @Override public int GetItemCount () {//TODO auto-generated Method stub return Beans.size (); /** * Get the type of message * * @Override public int getitemviewtype (int position) {//TODO auto-generated method stub ret
 Urn Beans.get (position). GetType ();  /** * Create Viewholder/@Override public Viewholder Oncreateviewholder (viewgroup parent, int viewtype) {//TODO
  auto-generated method stub View v = null;
  Viewholder holer = null; Switch (viewtype) {case Bean.x_type:v = Layoutinflater.from (Parent.getcontext ()). Inflate (r.layout.recylce_item_x, NULL);
   Holer = new Textholer (v);
  Break
   Case bean.y_type:v = Layoutinflater.from (Parent.getcontext ()). Inflate (r.layout.recylce_item_y, NULL);
   Holer = new Buttonholder (v);
  Break
   Case bean.z_type:v = Layoutinflater.from (Parent.getcontext ()). Inflate (r.layout.recylce_item_z, NULL);
   Holer = new Imageholer (v);
  Break
 return holer; /** * Binding Viewholder/@Override public void Onbindviewholder (viewholder holder, int position) {//TODO auto-g enerated method Stub switch (getitemviewtype (position)) {case Bean.X_TYPE:TextHoler Textholer = (textholer) Holde
   R
   Textholer.textView.setText (Beans.get (position). GetText ());
  Break
   Case Bean.Y_TYPE:ButtonHolder Buttonholder = (buttonholder) holder;
   ButtonHolder.button.setText (Beans.get (position). GetText ());
  Break Case Bean.Z_TYPE:ImageHoler Imageholer = (imagehoLER) holder; ImageHoler.Imageview.setImageResource (Android.
   R.drawable.checkbox_on_background);
  Break

 }
 }
}

The

is finally the code for the activity.

Package com.androidl.bob;
Import java.util.ArrayList;

Import java.util.List;
Import android.app.Activity;
Import Android.os.Bundle;
Import Android.support.v7.widget.LinearLayoutManager;

Import Android.support.v7.widget.RecyclerView;

Import COM.EXAMPLE.ANDROIDL.R; public class Mainactivity extends activity {@Override protected void onCreate (Bundle savedinstancestate) {//TODO
  auto-generated method Stub super.oncreate (savedinstancestate);
   Setcontentview (r.layout.main_activity);

Recyclerview Mrecyclerview = (recyclerview) Findviewbyid (R.id.my_recycler_view); Improve performance If you know this changes in content///does not change the size of the Recyclerview//MRECYCL

   Erview.sethasfixedsize (TRUE);
  Create layout manager Linearlayoutmanager Mlayoutmanager = new Linearlayoutmanager (this);
  Mlayoutmanager.setorientation (linearlayoutmanager.vertical);

  Mrecyclerview.setlayoutmanager (Mlayoutmanager); Initialize data list<bean> myDataSet = new Arraylist<bean> ();
  Mydataset.add (New Bean (Bean.z_type, "picture"));
  Mydataset.add (New Bean (Bean.x_type, "text"));
  Mydataset.add (New Bean (Bean.y_type, "button"));
  Mydataset.add (New Bean (Bean.z_type, "picture"));
  Mydataset.add (New Bean (Bean.x_type, "shit"));
  Mydataset.add (New Bean (Bean.x_type, "I Rub"));
  Mydataset.add (New Bean (Bean.z_type, "picture"));
  Mydataset.add (New Bean (Bean.y_type, "button"));
  Mydataset.add (New Bean (Bean.y_type, "button"));
  Mydataset.add (New Bean (Bean.x_type, "text"));
  Create adapter Recycleadapter madapter = new Recycleadapter (myDataSet);

 Mrecyclerview.setadapter (Madapter); 
 }

}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.