How to Customize RecyclerView Click Events and Draw Split Lines - Advanced UI-2

Keywords: Google Attribute Android github

1. Next to the previous blog we solved the RecyclerView Linear List Split Line drawing problem:
1. Effects:
We know that Google engineers don't have the same divider attribute set for RecyclerView as listView to draw split lines.So let's solve the RecyclerView problem today.The following results have been achieved:


2. Analyse how to draw:
I don't know you've seen LinearLayoutAppCompat do not. There are onMeasure,onDraw and other methods to draw split lines. You can see for yourself. In fact, the drawing process is similar to RecyclerView.This way, by finding out if there is a Divider method available: by guessing if there is an addItemDecoration method, we can see that the parameter type is ItemDecoration, then we click in to see the source code, and we will be happy to see that the ItemDecoration in RecyclerView is dedicated to processing and decorating the RecylerView source code as follows:

 /**
 * Draw any appropriate decorations into the Canvas supplied to the RecyclerView.
 * Any content drawn by this method will be drawn before the item views are drawn,
 * and will thus appear underneath the views.
 *
 * @param c Canvas to draw into
 * @param parent RecyclerView this ItemDecoration is drawing into
 * @param state The current state of RecyclerView
 */

  public void onDraw(Canvas c, RecyclerView parent, State state) {
            onDraw(c, parent);

  }

 /**
  * Retrieve any offsets for the given item. Each field of <code>outRect</code> specifies
  * the number of pixels that the item view should be inset by, 
  * similar to padding or margin.
  * The default implementation sets the bounds of outRect to 0 and returns.
  * */

 @Deprecated
 public void getItemOffsets(Rect outRect, int itemPosition,  
 RecyclerView parent) {
            outRect.set(0, 0, 0, 0);
 }

It is clear from the source that a rectangle is set as a dividing line through getItemOffsets.Use onDraw to set the rectangle to draw on the canvas.
3. Here's the code:
The basic code is not pasted here.Paste it out together behind.First, let's write a RecylerViewDivider class that inherits the onDraw and getItemOffsets required by RecyclerView.ItemDecoration overrides, as well as the construction methods. We need to know whether the direction of the linear layout list is horizontal or vertical, and the background picture where the splitter lines need to be drawn.I posted the code as follows:

public class RecylerViewDivider extends RecyclerView.ItemDecoration {
    private Context context;
    private int mOrignation;
    private Drawable mDrawble;
    private int[] attr=new int[]{android.R.attr.listDivider};
    public RecylerViewDivider(Context context,int mOrignation){

    }
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
    }

    @Override
    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
        super.getItemOffsets(outRect, itemPosition, parent);
    }
}
   We need a background picture of the dividing line as the dividing line, so let's define a background picture, private Drawable mDiveder, so we need a custom background picture or the default can be.Start with a default try followed by a custom splitter background.In the construction method, the background picture of the split line is initialized to determine the direction of the linear list, and the code is as follows:
 public RecylerViewDivider(Context context, int mOrignation) {
        //Get a custom background picture.
        TypedArray typedArray = context.obtainStyledAttributes(attr);
        mDrawble = typedArray.getDrawable(0);
        //Used to determine the direction of the list display
        getOrignation(mOrignation);

    }

    private void getOrignation(int mOrignation) {
        if (mOrignation!= LinearLayout.HORIZONTAL&&mOrignation!= LinearLayout.VERTICAL) {
            throw new ArithmeticException("Dude, did you pass in the direction enumeration type?");
        } else {
            this.mOrignation=mOrignation;
        }
    }

Next, let's set the offset of the rectangular dividing line in different directions.
1. Understand as shown in the figure: If it is a list in the vertical direction, then we set the Item vertical offset to the height of mDiveder.There is no splitter bar in other directions and no offset.So 0, understand as follows:

As shown in the figure above, we can calculate the offset height for rectangular entries that draw a vertical list:

            outRect.set(0, 0, 0, mDrawble.getIntrinsicHeight());


The horizontal list entry direction is also offset by the width, code as follows:

     outRect.set(0, 0, mDrawble.getIntrinsicWidth(), 0);

The location of the split entry and the fill code are pasted here:

 @Override
    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
        super.getItemOffsets(outRect, itemPosition, parent);
        if (mOrignation == LinearLayout.VERTICAL) {
            //If it's a vertical list, we can see that each item has a generated entry underneath it.Not in other directions
            outRect.set(0, 0, 0, mDrawble.getIntrinsicHeight());
        } else {
             //If it's a horizontal list, we can see that there is an entry on the right side of the item on display.Not in other directions.
            outRect.set(0, 0, mDrawble.getIntrinsicWidth(), 0);
        }
    }

Finally, all we need to do is draw the dividing lines between each Item.
First draw the dividing line in the direction of the vertical list:
1. Analyse with diagrams:

Let's write this part of the code:

  private void drawVertical(Canvas c, RecyclerView parent) {
        //Left and right are the same as the parent layout.So here we get the left and right positions
        int left = parent.getPaddingLeft();
        int right = parent.getWidth() - parent.getPaddingRight();
        int childcout = parent.getChildCount();
        for (int i = 0; i < childcout; i++) {
            //Gets the child control that gets the height of the item from the top of the parent control
            View childerView = parent.getChildAt(i);
            //Get properties of item
            RecyclerView.LayoutParams parames = (RecyclerView.LayoutParams) childerView.getLayoutParams();
            //Split line position
            int top = childerView.getBottom() + parames.bottomMargin + Math.round(ViewCompat.getTranslationY(childerView));
            int bottom = top + mDrawble.getIntrinsicHeight();
            mDrawble.setBounds(left, top, right, bottom);
            mDrawble.draw(c);
        }
    }

Also get the code for the horizontal list:

 private void drawHorizontal(Canvas c, RecyclerView parent) {
        int top = parent.getPaddingTop();
        int bottom = parent.getHeight()-parent.getPaddingBottom();
        int childcout = parent.getChildCount();
        for (int i = 0; i < childcout; i++) {
            //Gets the child control that gets the height of the item from the top of the parent control
            View childerView = parent.getChildAt(i);
            //Get properties of item
            RecyclerView.LayoutParams parames = (RecyclerView.LayoutParams) childerView.getLayoutParams();
            //Split line position
            int left = childerView.getRight() + parames.rightMargin + Math.round(ViewCompat.getTranslationY(childerView));
            int right = left + mDrawble.getIntrinsicWidth();
            mDrawble.setBounds(left, top, right, bottom);
            mDrawble.draw(c);
        }
    }

Finally set in Activity: a vertical list code is pasted here.

private void setData() {
        mAdapter = new MyRecyclerAdapter(mList);
        //LayoutManager Layout Manager, controls placement: linear placement,
        mRecylerview.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        mRecylerview.setAdapter(mAdapter);
        mAdapter.setOnItemClickListener(new MyRecyclerAdapter.OnItemClickListener() {
            @Override
            public void onItemClickListener(View view, int position) {
                Toast.makeText(MainActivity.this, "I am No." + position + "strip item", Toast.LENGTH_SHORT).show();
            }
        });
        mRecylerview.addItemDecoration(new RecylerViewDivider(this, LinearLayoutManager.HORIZONTAL));
    }

The final result is shown in the figure:

To sleep.It's 2 o'clock.The project download address is as follows:
https://github.com/luhenchang/Lsn2_MaterialDesign_RecyclerView.git

Posted by beckjoh on Tue, 04 Jun 2019 09:48:26 -0700