How to add a separator line for Recyclerview _android

Source: Internet
Author: User

I published my first technical document in Jane's book: Recyclerview Series: Recyclerview series (1) for Recyclerview Add header and footer, also very fortunate to get so many people support, This makes me eager to write the second article quickly. Today I'm going to talk about adding a divider line for Recyclerview.

I. Understanding the Childview in ListView and Recyclerview
in speaking for the item to join the nature of the line before, first to introduce, to understand the Childview, that is, usually we use the Listview,recyclerview in the getchildat (int position) What part of this return is Childview? What part is it? At first, I got it wrong, but after a comparison of two charts below, you know:


Item layout Layout_margin = = 0

Item layout Layout_margin = = 16DP

Here's what the code looks different:
The code for the first diagram, which is each list_item layout file (below), is as follows:

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android=
"http://schemas.android.com/apk/" Res/android "    android:orientation=" vertical "    
android:layout_width=" match_parent "    
android:layout_" height= "50DP" > 
  <textview  
  android:id= "@+id/list_item"  
  android:layout_width= "Match_parent" 
  android:layout_height= "match_parent"  
  android:gravity= "center"  
  android:textsize= "20SP"  
  Android:textcolor= "#262526"  
  android:background= "#08da1d"/>
</LinearLayout>

Code for the second picture:

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android=
"http://schemas.android.com/apk/" Res/android "    android:orientation=" vertical "    
android:layout_width=" match_parent "    
android:layout_" height= "50DP"
android:layout_margin= "16DP" > 
  <textview  
  android:id= "@+id/list_item"  
  Android:layout_width= "Match_parent" 
  android:layout_height= "match_parent"  
  android:gravity= "center"  
  android:textsize= "20sp"  
  android:textcolor= "#262526"  
  android:background= "#08da1d"/>
</LinearLayout>

To take a closer look, the difference between them is that the code in the second diagram is much more:

Android:layout_margin = "16DP"
It's just one more thing.

So here we should know what part of the Childview, is the green part of Figure two, margin this part does not belong to the Childview, but belongs to the Childview layout.

Now that we understand the childview, it's much simpler to understand the principle of adding a separator line.

Two. Understand the principle of adding a separator line

In ListView, Google provides us with Setdivider (drawable divider) to set the divider, so what does Google offer us to add a separator line in Recyclerview? By viewing the official document, it provides: Additemdecoration (recyclerview.itemdecoration Decor) This method sets the divider line, and that's the problem. What is Recyclerview.itemdecoration? Keep looking: It turns out to be a class that encapsulates three methods:
(1) void Getitemoffsets ()
(2) void OnDraw ()
(3) void Ondrawover ()

Through the above three methods, you can see, this is to draw themselves directly up, accurately said these methods are: add divider, mainly to find the location to add divider, and divider is written in drawable file. With OnDraw and ondrawover alike, we simply rewrite Getitemoffsets () and OnDraw () when we create our own decoration class to inherit recyclerview.itemdecoration. And Ondrawover, one of them is OK.

What is the use of the Getitemoffsets () method? Literally means the item is going to be offset, because we have added a divider between item and item, the line is actually a rectangle, which is also user-defined, since the line also has a long width and height, the above item is added to the divider line, the item below is going to pan down, The amount of translation is the height of the separator line. If you don't understand every relationship, it's easy to understand the code later.

Now we know how to add, that is, by painting, where is the painting? How do you determine the position of the painting? Look at the picture below:


Location diagram of the divider line

I'm taking the horizontal line now, from the above figure, it's easy to see that we draw the divider position between the layout of each item, note: between layouts.

OK, we've made sure where the painting is, so how do we determine the exact coordinates of the drawing line? That is, we want to be sure: the left of the divider line, top, right, Bottom. In adapter, it's easy to get every Childview by parent (the parent it's actually the part we see):
(1) Left:parent.getPaddingLeft ()
(2) Right:parent. GetWidth ()-parent.getpaddingright ();
(3) Top: Is the red line above: we have Childview.getbottom () to get the height of the item's bottom, that is, the blue wire position, the gap between the blue and red lines: This is the item layout file: Layout_marginbottom, Then the top position is the sum of the two.
(4) Bttom: Is the top plus the height of the divider line: top+ line height

Through the above analysis, you may know the principle of adding a separator line, do not understand and have no relationship, said it is not very clear, the following directly on the code, through the code to understand.

Three. Talk is cheap, show your code.

(1) First, first look at the main layout file: Activity_main.xml:

<?xml version= "1.0" encoding= "Utf-8"?>
 xmlns: Android= "http://schemas.android.com/apk/res/android"
 xmlns:tools= "Http://schemas.android.com/tools" 
 Android:layout_width= "Match_parent"
 android:layout_height= "match_parent"
 android:fitssystemwindows= " True "
 tools:context=" com.study.wnw.recyclerviewdivider.MainActivity >

 < Android.support.v7.widget.RecyclerView
  android:id= "@+id/recyclerview"
  android:layout_width= "Match_ Parent "
  android:layout_height=" match_parent > 
 </android.support.v7.widget.RecyclerView>
</android.support.design.widget.CoordinatorLayout>

I just joined a recyclerview in the area.

(2) Recyclerview layout file for each item: Item_view.xml

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android=
"http://schemas.android.com/apk/" Res/android "
    android:orientation=" vertical "
    android:layout_width=" match_parent " 
    android:layout_" height= "50DP"
    android:layout_margin= "16sp" >
 <textview
  android:id= "@+id/list_item"
  Android:layout_width= "Match_parent"
  android:layout_height= "match_parent"
  android:gravity= "center"
  android:textsize= "20sp"
  android:textcolor= "#f7f4f7"
  android:background= "#08da1d"/>
</LinearLayout>

There's nothing to be said about adding a textview to the inside to show the text

(3) Our Recyclerview adapter Myadapater.java:

Package com.study.wnw.recyclerviewdivider;
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.TextView;
Import java.util.List;
Import java.util.concurrent.CopyOnWriteArrayList; /** * Created by WNW on 16-5-22. */public class Myadapter extends Recyclerview.adapter<recyclerview.viewholder> {//define a set,
 Receive data and context from the activity, private list<string> mlist;

 Private context Mcontext;
  Myadapter (context context, list<string> List) {this.mcontext = context;
 This.mlist = list;
 The number of child received @Override public int getitemcount () {return mlist.size (); //Create Childview @Override public Recyclerview.viewholder oncreateviewholder (viewgroup parent, int viewtype) {View L
  Ayout = Layoutinflater.from (Mcontext). Inflate (R.layout.item_view, parent, false);
 return new Myholder (layout); //Bind data to each Childview @Override PUBlic void Onbindviewholder (recyclerview.viewholder holder, int position) {if (holder instanceof Myholder) {final Str
   ing itemtext = mlist.get (position);
  ((myholder) holder). Tv.settext (Itemtext);
  }//through holder to initialize each Childview content class Myholder extends recyclerview.viewholder{TextView TV;
   Public Myholder (View Itemview) {super (Itemview);
  TV = (TextView) Itemview.findviewbyid (R.id.list_item);

 }
 }
}

Well, there is no good to talk about, nor is this the focus of our article, the following focus here.

(4) Our custom Mydecoration.java: (Inherit recyclerview.itemdecoration)

Package com.study.wnw.recyclerviewdivider;
Import Android.content.Context;
Import Android.content.res.TypedArray;
Import Android.graphics.Canvas;
Import Android.graphics.Rect;
Import android.graphics.drawable.Drawable;
Import Android.support.v7.widget.LinearLayoutManager;
Import Android.support.v7.widget.RecyclerView;
Import Android.util.Log;

Import Android.view.View; /** * Created by WNW on 16-5-22.
 * * public class Mydecoration extends recyclerview.itemdecoration{the private context mcontext;
 Private drawable Mdivider;
 private int morientation;
 public static final int horizontal_list = linearlayoutmanager.horizontal;

 public static final int vertical_list = linearlayoutmanager.vertical; We add it by getting the Listdivider in the system properties, setting the public static final int[in the Apptheme in the system Atrrs = new int[]{Android.

 R.attr.listdivider};
  Public Mydecoration (context context, int orientation) {This.mcontext = context;
  Final TypedArray ta = context.obtainstyledattributes (Atrrs); This.mdivider = TA.GEtdrawable (0);
  Ta.recycle ();
 SetOrientation (orientation);  //Set the orientation of the screen public void setorientation (int orientation) {if (Orientation!= horizontal_list && Orientation!=  Vertical_list) {throw new IllegalArgumentException ("Invalid orientation");
 } morientation = orientation; @Override public void OnDraw (Canvas C, Recyclerview parent, recyclerview.state State) {if (morientation = = Horizo
  Ntal_list) {Drawverticalline (c, parent, state);
  }else {Drawhorizontalline (c, parent, state); //Draw horizontal line, where the parent is actually shown on the screen this part of the public void Drawhorizontalline (Canvas C, Recyclerview parent, Recyclerview.state St
  ATE) {int left = Parent.getpaddingleft ();
  int right = Parent.getwidth ()-parent.getpaddingright ();
  Final int childcount = Parent.getchildcount ();

   for (int i = 0; i < ChildCount. i++) {final View child = Parent.getchildat (i);
Get the layout information of the child final recyclerview.layoutparams params = (recyclerview.layoutparams) child.getlayoutparams ();   Final int top = Child.getbottom () + Params.bottommargin;
   final int bottom = top + mdivider.getintrinsicheight ();
   Mdivider.setbounds (left, top, right, bottom);
   Mdivider.draw (c);
  LOG.D ("WNW", Left + "" + Top + "" +right+ "" +bottom+ "" +i); //Draw vertical bar public void Drawverticalline (Canvas C, Recyclerview parent, recyclerview.state state) {int top = parent.ge
  Tpaddingtop ();
  int bottom = Parent.getheight ()-Parent.getpaddingbottom ();
  Final int childcount = Parent.getchildcount (); 

   for (int i = 0; i < ChildCount. i++) {final View child = Parent.getchildat (i);
   Get the layout information of the child final recyclerview.layoutparams params = (recyclerview.layoutparams) child.getlayoutparams ();
   Final int left = Child.getright () + Params.rightmargin;
   Final int right = left + mdivider.getintrinsicwidth ();
   Mdivider.setbounds (left, top, right, bottom);
  Mdivider.draw (c); }//Because the divider also has a long width, each item needs to be down or to the right offset @Override public void getitemoffsets (Rect outrect, View VIEW, Recyclerview Parent, recyclerview.state State) {if (morientation = = horizontal_list) {//Draw horizontal line, which is to offset the height of a split
  Rect.set (0, 0, 0, mdivider.getintrinsicheight ());
  }else {//Draw vertical bar, is to the right offset a split line width outrect.set (0, 0, mdivider.getintrinsicwidth (), 0);

 }
 }
}

From the code above, we also use the system properties to adapt to screen horizontal screen and vertical screen, and then determine the drawing horizontal, or vertical divider, in fact, we did three things, the first is: get to the system Listdivider, we are through it in the theme of the set, The following section (6) to see the code on the point of the know. The second thing: find where we need to add divider, find it from the OnDraw method, and add divider to it. The third is: Get the item offset.

(5) Look at our Mainactivity.java.

Package com.study.wnw.recyclerviewdivider;
Import Android.os.Bundle;
Import android.support.v7.app.AppCompatActivity;
Import Android.support.v7.widget.LinearLayoutManager;
Import Android.support.v7.widget.RecyclerView;
Import java.util.ArrayList;
Import java.util.List;

 public class Mainactivity extends appcompatactivity {//definition Recyclerview private recyclerview mrecyclerview = null;

 Defines a List collection that is used to store each of the data in Recyclerview private list<string> mdata = null; 

 Define a adapter private myadapter madapter;

 Define a Linearlayoutmanager private Linearlayoutmanager mlayoutmanager;
  @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);

  Setcontentview (R.layout.activity_main);
  Recyclerview three-step curved +layoutmanager Initview ();
  InitData ();
  Madapter = new Myadapter (this,mdata);
  Mrecyclerview.setlayoutmanager (Mlayoutmanager); 

  Mrecyclerview.setadapter (Madapter); This is to add our custom separator line mrecyclerview.additemdecoration (new mydecoration thiS, mydecoration.vertical_list));
  }//Initialize view private void Initview () {Mlayoutmanager = new Linearlayoutmanager (this);
 Mrecyclerview = (Recyclerview) Findviewbyid (R.id.recyclerview); //Initialize data loaded into Recyclerview, I'm just adding String type data to each item private void InitData () {mdata = new arraylist<string> (
  );
  for (int i = 0; i < i++) {Mdata.add ("Item" + i);

 }
 }
}

(6) drawable file of divider line divider: divider. Xml

<?xml version= "1.0" encoding= "Utf-8"?> <shape xmlns:android=
"http://schemas.android.com/apk/res/" Android "
 android:shape=" Rectangle >
 <solid android:color= "#7b7a7a"/>
 <size android: height= "1DP"/>
</shape>

We are here, painted a: rectangle, to fill it with color, there is a height, so that is done, the height of small, show is also a line: In fact, the essence of the line is rectangular. Here you can draw different types of divider according to your personal needs.

(7) in the Apptheme of Styles.xml, set Listdivider as our Divider.xml file:

<style name= "Apptheme" parent= "Theme.AppCompat.Light.DarkActionBar" >
 <item name= "Android:listdivider" "> @drawable/divider</item>
</style>

In this way, we set the listdivider of the system to our custom divider. Remember that we get the listdivider of the system in mydecoration, so that by using this property, we can associate our Divider.xml file with the Mydecoration.java.

All the work here is done, and the following shows the results of the operation:


Vertical Screen Effect Chart

Horizontal Screen Effect Chart

After a few hours of writing, finally finished, although only a function of adding a divider, but still want to understand as much as possible through their own language, to recognize its principles, so it is much simpler to do. In the beginning, I do not know how to use the night, but also refer to the articles written by others, especially the great God: Android Recyclerview Use full parsing experience art control, write a special stick, from which also learned some knowledge.

Well, this article is temporarily written here, the simple introduction of some Recyclerview divider line principle and add methods, I hope that we can communicate a lot, in a few days I will continue to write the next article, Recyclerview Series (3): Add Drop-down refresh and pull load for recyclerview. Finally, thank you, thanks to this platform, can let us communicate together, all learning.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.