Android Open Source Library V - Layout: The UI framework that Taobao and Tianmao are using, use it quickly!

Keywords: Android Attribute github xml


Preface

  • V-Layout is Ali's basic UI framework, which is used to quickly realize the complex layout of pages, and is widely used in Android version of Skycat Mobile Phone.

Electronic business graph

Github
  • During the May Day holiday, I made a detailed analysis of V-Layout. I will present a strategy of using V-Layout, source code analysis. I hope you will like it.

Catalog


Catalog

1. Why use V - Layout

Before explaining V - Layout, let's get to the point: Why use V - Layout?

1.1 background

  • UI performance consumption in Android comes mainly from two aspects:

    1. Layout hierarchy nesting leads to multiple measures/layout
    2. Creation and Destruction of View Controls
  • To solve these problems, the existing solutions are:

    1. Less Nested Layout
    2. Use basic spaces such as ListView/GirdView/RecyclerView to handle the recovery and reuse of Views.

However, many times we need to do a variety of types of layout under a long list to allocate various elements, especially the home page of e-commerce platform, layout elements structure is more complex and diverse. The following picture:


Electronic business graph

At this point, the solution changes: instead of reusing sub-Views, only one main reuse container (such as ListView or RecyclerView + Linear Layout Manager) is used, where nested components are directly spliced together to reduce the reuse capability.

1.2 problem

This approach will still lose the performance of Android applications.

1.3 Solution

  • Manage all layout types by customizing Layout Manager
  • That is, VirtualLayout, Ali's basic UI framework project, uses this approach to solve the above problems.

2. introduction

  • Definition: Virtual Layout is Ali's basic UI framework project
  • Function: Fast mixing of complex layout formats

Design sketch

3. Application scenarios

  • Complex layout formats, such as floating layout, grid layout, column layout, one-drag N layout, waterfall flow layout, can also be combined to use these layouts.
  • Specific scenarios are: e-commerce platform home page, activity page, etc.

    V - Layout is now widely used in the Android version of mobile phone Tianmao & Taobao


Practical application effect chart

4. Principle analysis

The essential principle of V-Layout is to quickly realize the requirement of composite layout by customizing a Virtual Layout Manager (inherited from Layout Manager) to manage a series of Layout Helpers and handing over specific layout capabilities to Layout Helper.

  1. Each LayoutHelper is responsible for layout within a certain range of pages
  2. V - Layout implements 10 default layouts by default: (corresponding to Layout Helper with the same name)

    Layout type

4.1 Source Class Description

The source class diagram of V - Layout is as follows:


UML class diagram

1.RecyclerView

  • Definition: Subject of Page Layout
  • Special note: Bind Virtual Layout Adapter (inheritance Adapter) in the V - layout Framework & Virtual Layout Manager (inheritance Layout Manager)

2. VirtualLayoutAdapter

  • Definition: Data adapter.

    Adaper inherited from the system

  • Role: Create Components & Bind Data to Components
  • Additional: Two interfaces are defined:
    1. getLayoutHelper(): A LayoutHelper (): Used to return a component corresponding to a location
    2. setLayoutHelpers(): A series of LayoutHelpers required to call this method to set up the entire page

      The implementation of these two methods is delegated to Virtual Layout Manager.

3. VirtualLayoutManager

  • Definition: Layout Manager

    Linear Layout Manager inherited from the system

  • Effect:
    1. Call layoutChunk () of VirtualLayoutManager when RecyclerView loads or slides, returning which blank areas are currently available for the component to be placed
    2. Manage the LayoutHelper list
  • Additional: Implementation of getLayoutHelper () and setLayoutHelpers () of Virtual LayoutAdapter

4. LayoutHelperFinder

  • Definition: LayoutHelper Finder
  • Function: Find the corresponding Layout Helper according to the page status and return it to Virtual Layout Manager
    1. Virtual Layout Manager holds a Layout Helper Finder
    2. When layoutChunck () is called, a location parameter is passed in telling VirtualLayoutManager which component to lay out at the moment.
    3. Virtual Layout Manager notifies the holding Layout Helper Finder to find the Layout Helper corresponding to the location of the incoming parameter (each Layout Helper binds the start and end locations of the layout area it is responsible for)

5. LayoutHelper

  • Definition: Layout Assistant
  • Role: Responsible for specific layout logic
  • It defines a series of interfaces for communicating with Virtual Layout Manager:
Interface Effect
isOutOfRange() Tell Virtual Layout Manager whether the location it passes over is in the current Layout Helper layout area;
setRange() Set the layout area currently in LayoutHelper's charge
doLayout() Real Layout Logic Interface
beforeLayout() Do some front-end work before layout
afterLayout() Do some post-work after the layout is completed

6. MarginLayoutHelper

  • Definition: inherited from Layout Helper
  • Function: Extend Layout Helper to provide the computing functions of padding and margin in layout.

7. BaseLayoutHelper

  • Definition: Layer 1 implementation of Margin Layout Helper
  • Function: Fill in the current LayoutHelper's logic of specific area background color, background image and so on within the scope of the screen

8. SubLayout Helper

  • Definition: Layer 2 implementation of Margin Layout Helper
  • Role: Responsible for specific layout logic
    1. Each seed Layout Helper is responsible for a layout logic
    2. Focus on the realization of beforeLayout(), doLayout(), afterLayout()
    3. In particular, doLayout(): Gets a set of components, calculates the size of components, and lays out the interface.
  • V - Layout implements 10 default layouts by default: (corresponding to Layout Helper with the same name)

Layout type

Details will be given below.

  • Special attention should be paid to:
    1. Each Layout Helper is responsible for laying out a batch of components within the scope of a component. If the types of components within different components are the same, reuse can be reclaimed in the sliding process. Therefore, the recovery granularity is fine and can be reused across layout types.
    2. Support Extended External: Register a new Layout Helper to achieve a special layout. Details will be given below.

After introducing the classes, I will analyze the workflow of V - Layout in detail.

4.2 Workflow

  • V-Layout's workflow is divided into initialization-layout process. The following picture:

Workflow
  • Next, I will give a detailed analysis of the initialization-layout process.

4.2.1 Initialization

  • Before using V - layout to quickly implement complex layout, a series of initialization work is needed.

    The initialization process is basically the same as the ordinary RecyclerView + LayoutManager initialization process: the user of Vlayout


Initialization process

The initialization here is actually the initialization work that users need to do when using V - layout. I will explain it in more detail in the following examples.

4.2.2 Specific Layout Flow

  • When initialization is completed, a layout process is performed whenever the user has just opened the page to render the layout for the first time or when the user slides the page.
  • The essence of layout process is to customize Virtual Layout Manager to continuously obtain page status and find the corresponding Layout Helper through Layout Helper Finder, so as to realize the corresponding layout logic, so as to quickly meet the needs of composite layout.
  • The specific process is as follows

Layout process

summary

Here's a diagram to summarize the principle of V - Layout - workflow


Principle-Workflow

After that, how do I use V - Layout?

5. Use steps

  • The use of V - Layout is actually the initialization work mentioned above.
  • The steps are as follows:

Using steps

I will elaborate on each step below.

Step 1: Create RecyclerView & VirtualLayoutManager objects and bind them

recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        // Create RecyclerView objects

        VirtualLayoutManager layoutManager = new VirtualLayoutManager(this);
        // Create a VirtualLayoutManager object
        // At the same time, a LayoutHelperFinder object is created internally for subsequent LayoutHelper lookups.

        recyclerView.setLayoutManager(layoutManager);
        // Binding Virtual Layout Manager to recyclerView

Step 2: Set the recycle reuse pool size

If there are many views of the same type on the screen, you need to set an appropriate size to prevent re-creating the View when scrolling back and forth.

// Setting up Component Reuse Recycling Pool
        RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
        recyclerView.setRecycledViewPool(viewPool);
        viewPool.setMaxRecycledViews(0, 10);

Step 3: Set up the Adapter

There are two ways to set up the Adapter of V - Layout:

  • Mode 1: Inheritance from Delegate Adapter
  • Mode 2: Inheritance from Virtual Layout Adapter
    Details will be given below:

Mode 1: Inheritance from Delegate Adapter

  • Definition: Delegate Adapter is a V - Layout custom adapter for managing Layout Helper

    Inheritance from Virtual Layout Adapter

  • Function: By managing different Layout Helper layouts and then different Layout Helper layouts, different combinatorial layouts can be used
    1. Special note: Although LayoutHelper cannot be bound directly, it has an internal class adapter inherited from RecyclerView.Adapter that can bind LayoutHelper.
    2. That is, through a List, the bound Adapter is packaged and Delegate Adapter is put away, so that different layouts can be combined.
  • Specific practices:
    1. Writing is very similar to the Adapter that comes with the replication system: only the onCreateLayoutHelper method needs to be overloaded more than the Recycler Adapter that comes with the system, and the rest are similar
    2. See my article about the use of Recycler Adapter in Android system Android development: full analysis of ListView, AdapterView and RecyclerView
public class MyAdapter extends DelegateAdapter.Adapter<MyAdapter.MainViewHolder> {

// Multiple load onCreateLayoutHelper () is required than the Recycler Adapter that comes with the system.

    @Override
    public LayoutHelper onCreateLayoutHelper() {
        return layoutHelper;
    }

... // The rest of the writing is the same as the Adapter that comes with the copy system.
}

Mode 2: Inheritance from Virtual Layout Adapter

  • Definition: When complex requirements need to be implemented, a custom adapter can be implemented by inheriting the Virtual Layout Adapter

  • Specific use

public class MyAdapter extends VirtualLayoutAdapter {
   ...// Custom Adapter Logic
}

Step 4: Create the corresponding Layout Helper based on the data list

  • The system encapsulates the following layout types (corresponding to Layout Helper of the same name)

Layout type
  • Specific uses are as follows:

1. Linear Layout Helper

  • Layout description: Layout subelements (Item s) are laid out linearly

Sketch Map
  • Specific use
/**
    Setting up Linear Layout
       */
        LinearLayoutHelper linearLayoutHelper = new LinearLayoutHelper();
        // Create the corresponding LayoutHelper object

 // Common attributes for all layouts (attributes are described in detail below)
        linearLayoutHelper.setItemCount(4);// Set the number of Item s in the layout
        linearLayoutHelper.setPadding(10,10,10,10);// Set the distance between the child elements of LayoutHelper and the edge of LayoutHelper
        linearLayoutHelper.setMargin(10,10,10,10);// Set the distance between the LayoutHelper edge and the parent control (RecyclerView)
        linearLayoutHelper.setBgColor(Color.GRAY);// Set the background color
        linearLayoutHelper.setAspectRatio(6);// Set the ratio of width to height for each line layout in the layout

 // linearLayoutHelper's unique attributes
        linearLayoutHelper.setDividerHeight(1); // Set the distance of Item per row

1. Common attributes of all layouts:

a. setItemCount property

  • Function: Set the number of Item s in the entire layout

    If the total number of Items set is different from the number returned by the Adapter's getItemCount() method, it will depend on the latter.


Sketch Map
  • Specific use
// Interface hint
    public void setItemCount(int Count)

// Specific use
        linearLayoutHelper.setItemCount(4);

B. Adding & Margin attributes

  • Definition: Both have the meaning of margin, but they have different definitions of margin:

    1. Padding: The distance between the child elements of LayoutHelper and the edge of LayoutHelper.
    2. Margin: The distance between the edge of LayoutHelper and the parent control (RecyclerView). Specifically as follows:

      Sketch Map
  • Specific use

// Interface hint
    public void setPadding(int leftPadding, int topPadding, int rightPadding, int bottomPadding)
    public void setMargin(int leftMargin, int topMargin, int rightMargin, int bottomMargin)

// Specific use
        linearLayoutHelper.setPadding(10,10,10,10);
        // Set the distance between the child elements of LayoutHelper and the edge of LayoutHelper

        linearLayoutHelper.setMargin(10,10,10,10);
        // Set the distance between the LayoutHelper edge and the parent control (RecyclerView)

c. bgColor attribute

  • Function: Set the layout background color
  • Specific use:
// Interface hint
public void setBgColor(int bgColor)

// Specific use
linearLayoutHelper.setBgColor(Color.YELLOW);

d. aspectRatio attribute

  • Function: Set the ratio of width to height of each line layout in the layout. Following chart

Sketch Map
  • Specific use
// Interface hint
public void setAspectRatio(float aspectRatio);
// aspectRatio defined by LayoutHelper

((VirutalLayoutManager.LayoutParams) layoutParams).mAspectRatio
// aspectRatio defined by LayoutParams of views
// After LayoutHelper calculates the view width, it is used to determine the view height. It covers the view height calculated by LayoutHelper's aspectRatio, so it has a higher priority.

// Specific use
        linearLayoutHelper.setAspectRatio(6);

2. Description of the unique attributes of the Linear Layout Helper layout

a. dividerHeight attribute

  • Function: Set the distance between Item s per row

    The set interval superimposes the interval added by addItemDecoration () of RecyclerView


Sketch Map
  • Specific use
// Interface hint
public void setDividerHeight(int dividerHeight)

// Specific use
 linearLayoutHelper.setDividerHeight(1);

2. Grid Layout

  • Layout description: Item s in the layout are arranged in grid form

Sketch Map
  • Specific use
        /**
        Setting up Grid Layout
        */
        GridLayoutHelper gridLayoutHelper = new GridLayoutHelper(3);
        // Set the number of grids per row in the constructor

        // Public attribute
        gridLayoutHelper.setItemCount(6);// Set the number of Item s in the layout
        gridLayoutHelper.setPadding(20, 20, 20, 20);// Set the distance between the child elements of LayoutHelper and the edge of LayoutHelper
        gridLayoutHelper.setMargin(20, 20, 20, 20);// Set the distance between the LayoutHelper edge and the parent control (RecyclerView)
        gridLayoutHelper.setBgColor(Color.GRAY);// Set the background color
        gridLayoutHelper.setAspectRatio(6);// Set the ratio of width to height for each line layout in the layout

        // Specific attributes of gridLayoutHelper (detailed below)
        gridLayoutHelper.setWeights(new float[]{40, 30, 30});//Set the ratio of the width of each grid to the total width of each row in each row
        gridLayoutHelper.setVGap(20);// Control the vertical spacing between sub-elements
        gridLayoutHelper.setHGap(20);// Controlling horizontal spacing between sub-elements
        gridLayoutHelper.setAutoExpand(false);//Whether to fill the blank area automatically
        gridLayoutHelper.setSpanCount(3);// Set how many grids per row
        // Control the number of meshes occupied by an Item by customizing SpanSizeLookup
        gridLayoutHelper.setSpanSizeLookup(new GridLayoutHelper.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                if (position > 7 ) {
                    return 3;
                    // After the seventh position, each Item occupies three grids
                }else {
                    return 2;
                    // Before the seventh position, each Item occupies two grids
                }
            }
        });
Specific attributes of GridLayoutHelper layout

a. weights attributes

  • Role: Set the ratio of the width of each grid to the total width of each row in each row
    1. By default, the width of each grid in each row is equal
    2. The weights attribute is a float array, each representing the percentage of the total width of each row in the grid; the total is 100, otherwise the layout will exceed the container width;
    3. If there are four columns in the layout, the length of weights should also be 4; if the length is greater than 4, the extra part does not participate in the width calculation; if less than 4, the insufficient part divides the remaining space by default.

Sketch Map
  • Specific use
// Interface hint
public void setWeights(float[] weights)

// Specific use
gridLayoutHelper.setWeights(new float[]{40, 30, 30});

b. vGap, hGap attributes

  • Function: Control the vertical and horizontal spacing between sub-elements respectively.

Sketch Map
  • Specific use
// Interface hint
    public void setHGap(int hGap)
    public void setVGap(int vGap)

// Specific use
    gridLayoutHelper.setVGap(20);// Control the vertical spacing between sub-elements
    gridLayoutHelper.setHGap(20);// Controlling horizontal spacing between sub-elements

c. spanCount, spanSizeLookup attributes

  • Effect:
    1. spanCount: Set how many grids per row
    2. spanSizeLookup: Sets how many grids each Item occupies (default = 1)

Sketch Map
  • Specific use
// Interface hint
public void setSpanCount(int spanCount)
public void setSpanSizeLookup(SpanSizeLookup spanSizeLookup)

// Specific use
        gridLayoutHelper.setSpanCount(5);// Set how many grids per row

        // Control the number of meshes occupied by an Item by customizing SpanSizeLookup
        gridLayoutHelper.setSpanSizeLookup(new GridLayoutHelper.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                if (position > 7 ) {
                    return 3;
                    // After the seventh position, each Item occupies three grids
                }else {
                    return 2;
                    // Before the seventh position, each Item occupies two grids
                }
            }
        });

d. autoExpand attribute

  • Function: When the number of items in a row is < (number of grid columns per row - span Count value / two grid-setSpanSizeLookup per Item), whether the blank area is filled automatically or not
    1. If autoExpand=true, the total width of the view fills the available area.
    2. Otherwise, a blank area will be left on the screen.

Sketch Map
  • Specific use
// Interface hint
public void setAutoExpand(boolean isAutoExpand)

// Specific use
gridLayoutHelper.setAutoExpand(false);

3. Fix Layout Helper

  • Layout description: Item fixed position in layout

    Fixed somewhere on the screen and not dragged & not scrolled along with the page. The following picture: (upper left corner)


Fixed layout
  • Specific use
/**
         Setting Fixed Layout
         */

        FixLayoutHelper fixLayoutHelper = new FixLayoutHelper(FixLayoutHelper.TOP_LEFT,40,100);
        // Description of parameters:
        // Parameter 1: Set alignType when sucking edges - There are four values: TOP_LEFT (default), TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT.
        // Parametric 2: offset x of reference position
        // Parametric 3: offset y of reference position


        // Public attribute
        fixLayoutHelper.setItemCount(1);// Set the number of Item s in the layout
        // As you can see from the source code that sets the number of Item s, a FixLayoutHelper can only set one.
//        @Override
//        public void setItemCount(int itemCount) {
//            if (itemCount > 0) {
//                super.setItemCount(1);
//            } else {
//                super.setItemCount(0);
//            }
//        }
        fixLayoutHelper.setPadding(20, 20, 20, 20);// Set the distance between the child elements of LayoutHelper and the edge of LayoutHelper
        fixLayoutHelper.setMargin(20, 20, 20, 20);// Set the distance between the LayoutHelper edge and the parent control (RecyclerView)
        fixLayoutHelper.setBgColor(Color.GRAY);// Set the background color
        fixLayoutHelper.setAspectRatio(6);// Set the ratio of width to height for each line layout in the layout

        // FixeLayoutHelper-specific attributes
        fixLayoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT);// Setting alignType
        fixLayoutHelper.setX(30);// Setting the transverse offset of the reference position X
        fixLayoutHelper.setY(50);// Setting the vertical offset Y of the reference position
FixLayoutHelper Specific Attribute Description

a. AlignType, x, y attributes

  • Effect:
    1. alignType: Suction Benchmark Type

      There are four values: TOP_LEFT (default), TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT. See the diagram below for details.

    2. x: Transverse offset of reference position
    3. y: Longitudinal offset of reference position

Sketch Map
  • Acting objects: attributes of FixLayoutHelper, ScrollFixLayoutHelper, FloatLayoutHelper
// Interface hint
public void setAlignType(int alignType)
public void setX(int x)
public void setY(int y)

// Specific use
fixLayoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT);
fixLayoutHelper.setX(30);
fixLayoutHelper.setY(50);

4. ScrollFix Layout Helper

  • Layout description: Item fixed position in layout
    1. Fixed somewhere on the screen and not dragged & not scrolled along with the page (inherited from Fix Layout Helper)
    2. The only difference is that you can freely set when the Item will be displayed (to the top / bottom), as shown in the following figure: (upper left corner)
    3. Requirement scenario: To display the button function of "one button to the top" at the bottom of the page

The following schematic diagram shows that the layout is displayed in the upper left corner by sliding to the bottom.


Slide to the bottom to show in the upper left corner
  • Specific use
/**
         Setting Optional Fixed Layout
         */

        ScrollFixLayoutHelper scrollFixLayoutHelper = new ScrollFixLayoutHelper(ScrollFixLayoutHelper.TOP_RIGHT,0,0);
        // Description of parameters:
        // Parameter 1: Set alignType when sucking edges - There are four values: TOP_LEFT (default), TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT.
        // Parametric 2: offset x of reference position
        // Parametric 3: offset y of reference position

        // Public attribute
        scrollFixLayoutHelper.setItemCount(1);// Set the number of Item s in the layout
        // As you can see from the source code that sets the number of Item s, a FixLayoutHelper can only set one.
//        @Override
//        public void setItemCount(int itemCount) {
//            if (itemCount > 0) {
//                super.setItemCount(1);
//            } else {
//                super.setItemCount(0);
//            }
//        }
        scrollFixLayoutHelper.setPadding(20, 20, 20, 20);// Set the distance between the child elements of LayoutHelper and the edge of LayoutHelper
        scrollFixLayoutHelper.setMargin(20, 20, 20, 20);// Set the distance between the LayoutHelper edge and the parent control (RecyclerView)
        scrollFixLayoutHelper.setBgColor(Color.GRAY);// Set the background color
        scrollFixLayoutHelper.setAspectRatio(6);// Set the ratio of width to height for each line layout in the layout

        // FixeLayoutHelper-specific attributes
     scrollFixLayoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT);// Setting alignType
        scrollFixLayoutHelper.setX(30);// Setting the transverse offset of the reference position X
        scrollFixLayoutHelper.setY(50);// Setting the vertical offset Y of the reference position
        scrollFixLayoutHelper.setShowType(ScrollFixLayoutHelper.SHOW_ON_ENTER);// Setting the display mode of Item
ScrollFixLayoutHelper Specific Attribute Description

a. AlignType, x, y attributes

  • Effect:
    1. alignType: Suction Benchmark Type

      There are four values: TOP_LEFT (default), TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT. See the diagram below for details.

    2. x: Transverse offset of reference position
    3. y: Longitudinal offset of reference position

Sketch Map
  • Specific use
// Interface hint
public void setAlignType(int alignType)
public void setX(int x)
public void setY(int y)

// Specific use
ScrollFixLayoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT);
ScrollFixLayoutHelper.setX(30);
ScrollFixLayoutHelper.setY(50);

b. ShowType attribute

  • Function: Set the display mode of Item

    There are three display modes

    1. SHOW_ALWAYS: Always show (i.e. the same effect as the fixed layout)
    2. SHOW_ON_ENTER: The view is not displayed by default, but only when the page scrolls to the view position.
    3. SHOW_ON_LEAVE: The view is not displayed by default, but only when the page rolls out of the view position.
  • Specific use

// Interface hint
public void setShowType(int showType)

// Specific use
scrollFixLayoutHelper.setShowType(ScrollFixLayoutHelper.SHOW_ON_ENTER);

5. Float Layout Helper

  • Layout description: There is only one Item in the layout.
    1. It can be dragged at will, but eventually it will be sucked to both sides.
    2. Do not move with page scroll

Sketch Map
  • Specific use
/**
         Setting Floating Layout
         */
        FloatLayoutHelper floatLayoutHelper = new FloatLayoutHelper();
        // Create FloatLayoutHelper objects

        // Public attribute
        floatLayoutHelper.setItemCount(1);// Set the number of Item s in the layout
        // As you can see from the source code that sets the number of Item s, a FixLayoutHelper can only set one.
//        @Override
//        public void setItemCount(int itemCount) {
//            if (itemCount > 0) {
//                super.setItemCount(1);
//            } else {
//                super.setItemCount(0);
//            }
//        }
        floatLayoutHelper.setPadding(20, 20, 20, 20);// Set the distance between the child elements of LayoutHelper and the edge of LayoutHelper
        floatLayoutHelper.setMargin(20, 20, 20, 20);// Set the distance between the LayoutHelper edge and the parent control (RecyclerView)
        floatLayoutHelper.setBgColor(Color.GRAY);// Set the background color
        floatLayoutHelper.setAspectRatio(6);// Set the ratio of width to height for each line layout in the layout

        // floatLayoutHelper's unique attributes
        floatLayoutHelper.setDefaultLocation(300,300);// Setting the initial location of Item in the layout

6. Column Layout Helper

  • Layout Description: This layout has only one column (which has multiple Item s)

    It can be understood as a linear layout with only one line.


Sketch Map
/**
         Set up the layout of the grid
         */
        ColumnLayoutHelper columnLayoutHelper = new ColumnLayoutHelper();
        // create object

        // Public attribute
        columnLayoutHelper.setItemCount(3);// Set the number of Item s in the layout
        columnLayoutHelper.setPadding(20, 20, 20, 20);// Set the distance between the child elements of LayoutHelper and the edge of LayoutHelper
        columnLayoutHelper.setMargin(20, 20, 20, 20);// Set the distance between the LayoutHelper edge and the parent control (RecyclerView)
        columnLayoutHelper.setBgColor(Color.GRAY);// Set the background color
        columnLayoutHelper.setAspectRatio(6);// Set the ratio of width to height for each line layout in the layout

        // Column Layout Helper's unique properties
        columnLayoutHelper.setWeights(new float[]{30, 40, 30});// Set the ratio of each Item to the total width of the row
        // Explain the Weigths attributes above

7. Single Layout Helper

  • Layout description: Layout has only one column, which has only one Item

Sketch Map
  • Specific use
/**
         Setting up the layout of the banner
         */

        SingleLayoutHelper singleLayoutHelper = new SingleLayoutHelper();

        // Public attribute
        singleLayoutHelper.setItemCount(3);// Set the number of Item s in the layout
        singleLayoutHelper.setPadding(20, 20, 20, 20);// Set the distance between the child elements of LayoutHelper and the edge of LayoutHelper
        singleLayoutHelper.setMargin(20, 20, 20, 20);// Set the distance between the LayoutHelper edge and the parent control (RecyclerView)
        singleLayoutHelper.setBgColor(Color.GRAY);// Set the background color
        singleLayoutHelper.setAspectRatio(6);// Set the ratio of width to height for each line layout in the layout

8. One Plus N Layout Helper

  • Layout Description: The layout is divided into different proportions, up to 1 drag 4. Specifically as follows

Sketch 1

Sketch 2
  • Specific use
/**
         Set 1 drag N layout
         */
        OnePlusNLayoutHelper onePlusNLayoutHelper = new OnePlusNLayoutHelper(5);
        // The number of Item s displayed in the constructor is passed in
        // A maximum of four delays, or five delays

        // Public attribute
        onePlusNLayoutHelper.setItemCount(3);// Set the number of Item s in the layout
        onePlusNLayoutHelper.setPadding(20, 20, 20, 20);// Set the distance between the child elements of LayoutHelper and the edge of LayoutHelper
        onePlusNLayoutHelper.setMargin(20, 20, 20, 20);// Set the distance between the LayoutHelper edge and the parent control (RecyclerView)
        onePlusNLayoutHelper.setBgColor(Color.GRAY);// Set the background color
        onePlusNLayoutHelper.setAspectRatio(3);// Set the ratio of width to height for each line layout in the layout

9. Sticky Layout Helper

  • Layout description: Layout has only one Item. The display logic is as follows:

    1. When it contains components that are visible on the screen, it scrolls like a normal component as the page scrolls.
    2. When the component is about to be slid out of the screen and returned, it can be sucked to the top or bottom of the screen to achieve a suction effect.
  • Sketch (suck on top)


Sketch Map
  • Specific use
        /**
         Setting up suction edge layout
         */
        StickyLayoutHelper stickyLayoutHelper = new StickyLayoutHelper();

        // Public attribute
        stickyLayoutHelper.setItemCount(3);// Set the number of Item s in the layout
        stickyLayoutHelper.setPadding(20, 20, 20, 20);// Set the distance between the child elements of LayoutHelper and the edge of LayoutHelper
        stickyLayoutHelper.setMargin(20, 20, 20, 20);// Set the distance between the LayoutHelper edge and the parent control (RecyclerView)
        stickyLayoutHelper.setBgColor(Color.GRAY);// Set the background color
        stickyLayoutHelper.setAspectRatio(3);// Set the ratio of width to height for each line layout in the layout

        // Specific attributes
        stickyLayoutHelper.setStickyStart(true);
        // true = component sucked on top
        // false = component sucked at the bottom

        stickyLayoutHelper.setOffset(100);// Setting offset of suction edge position

        Adapter_StickyLayout = new MyAdapter(this, stickyLayoutHelper,1, listItem) {
            // Set the total number of data to display, where 1
            // To show the effect, set the first data of the layout to Stick by rewriting onBindViewHolder().
            @Override
            public void onBindViewHolder(MainViewHolder holder, int position) {
                super.onBindViewHolder(holder, position);
                if (position == 0) {
                    holder.Text.setText("Stick");
                }
            }
        };

        adapters.add(Adapter_StickyLayout) ;
        // Add the current Adapter to the Adapter list

stickyStart, offset attribute description

  • Effect:

    1. stickyStart: Set the suction position

      When the position of the view is within the scope of the screen, the view scrolls as the page scrolls; when the position of the view slides out of the screen, Sticky Layout Helper fixes the view at the top (stickyStart = true) or at the bottom (stickyStart = false).

    2. Offset: Set the offset of the suction edge

  • Specific use

// Interface hint
        public void setStickyStart(boolean stickyStart)
        public void setOffset(int offset)

// Specific use
        stickyLayoutHelper.setStickyStart(true);
        // true = component sucked on top
        // false = component sucked at the bottom
        stickyLayoutHelper.setOffset(100);// Setting offset of suction edge position

10. Staggered Grid Layout Helper

  • Layout description: Layout in the form of grid. Similar to grid layout, the difference is that:
    • The Item height of each column in the grid layout is equal.
    • The Item height of each column in the waterfall flow layout can be unequal.

Sketch Map
  • Specific use
        /**
         Setting Waterfall Flow Layout
         */

        StaggeredGridLayoutHelper staggeredGridLayoutHelper = new StaggeredGridLayoutHelper();
        // create object

        // Public attribute
        staggeredGridLayoutHelper.setItemCount(20);// Set the number of Item s in the layout
        staggeredGridLayoutHelper.setPadding(20, 20, 20, 20);// Set the distance between the child elements of LayoutHelper and the edge of LayoutHelper
        staggeredGridLayoutHelper.setMargin(20, 20, 20, 20);// Set the distance between the LayoutHelper edge and the parent control (RecyclerView)
        staggeredGridLayoutHelper.setBgColor(Color.GRAY);// Set the background color
        staggeredGridLayoutHelper.setAspectRatio(3);// Set the ratio of width to height for each line layout in the layout

        // Specific attributes
        staggeredGridLayoutHelper.setLane(3);// Set the number of Item s per row that control the waterfall flow
        staggeredGridLayoutHelper.setHGap(20);// Set horizontal spacing between child elements
        staggeredGridLayoutHelper.setVGap(15);// Set the vertical spacing between child elements

Custom Layout Helper

In addition to using the default LayoutHelper layout provided by the system, developers can also customize LayoutHelper to achieve custom layout styles. There are three ways:

  1. Inherit BaseLayout Helper: Top-down order - Internal View can be recycled by row layout; mainly implement layoutViews(), computeAlignOffset() and other methods.

    Linear Layout Helper and GridLayout Helper are all implemented by this method.

  2. Inheritance of AbstractFull Fill Layout Helper: View s within some layouts are not arranged from top to bottom (that is, the data order in Adatper is inconsistent with the order of physical views, so it may not be possible to lay out and recycle in data order), and a one-time layout is required.
    Recycling. Mainly implements layoutViews() and other methods

    OnePlus NLayout Helper is implemented by this method

  3. Inherit the FixArea LayoutHelper: fix type layout, and the child nodes do not scroll as the page scrolls. The main implementation methods are layoutViews(), beforeLayout(), afterLayout().

    Fix Layout Helper is implemented with this method

Step 5: Give the generated LayoutHelper to the Adapter and bind it to the RecyclerView object

The approach here will vary depending on the setup of the Adapter in Step 3

<-- Adapter Inherit from DelegateAdapter -->

// Step 1: Set the Adapter List (and also the LayoutHelper List)
        List<DelegateAdapter.Adapter> adapters = new LinkedList<>();

// Step 2: Create a custom Adapter object & bind data & bind the corresponding LayoutHelper above
// To bind, you need to show Layout Helper, just two of which are shown here.
        MyAdapter Adapter_linearLayout    = new MyAdapter(this, linearLayoutHelper,ListItem);
// ListItem is data that needs to be bound (depending on how your Adapter defines it)

        MyAdapter Adapter_gridLayoutHelper    = new MyAdapter(this, gridLayoutHelper,ListItem);

// Step 3: Put the created adapter object in the DelegateAdapter.Adapter list
        adapters.add(Adapter_linearLayout ) ;
        adapters.add(Adapter_gridLayoutHelper ) ;

// Step 4: Create the DelegateAdapter object & bind the layoutManager to the DelegateAdapter
DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager);

// Step 5: Bind the Delegate Adapter. Adapter list to Delegate Adapter
 delegateAdapter.setAdapters(adapters);

// Step 6: Bind the delegate adapter to recyclerView
recyclerView.setAdapter(delegateAdapter);



<-- Adapter Inherit from VirtualLayoutAdapter -->

// Step 1: Set up the LayoutHelper list
        List<LayoutHelper> helpers = new LinkedList<>();

// Step 2: Bind the corresponding LayoutHelper above
helpers.add(Adapter_linearLayout );
helpers.add(Adapter_gridLayoutHelper ) ;

// Step 3: Create a custom MyAdapter object & Bind Layout Manager
MyAdapter myAdapter = new MyAdapter(layoutManager);

// Step 4: Pass the layoutHelper list to adapter
myAdapter.setLayoutHelpers(helpers);

// Step 5: Bind adapter to recyclerView
recycler.setAdapter(myAdapter);

At this point, the use process is explained.

6. Illustration of examples

  • The advantage of V-Layout is that it combines different layouts quickly.
  • Next, I'll use an example to quickly assemble the layout using V - Layout, as described in the steps above.

Step 1: Add dependencies to Android - Gradle

compile ('com.alibaba.android:vlayout:1.0.3@aar') {
        transitive = true
    }

Step 2: Define the master xml layout

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="scut.carson_ho.v_layoutusage.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="horizontal" />
</RelativeLayout>

Step 3: Define the xml layout for each sub-element (Item) of RecyclerView

item.xml

The Item layout defined here is the usual top-word and bottom-word layout.

<?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="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="New Text"
        android:id="@+id/Item" />

    <ImageView
        android:layout_alignParentRight="true"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/Image"/>

</LinearLayout>

Step 4: Set up the Adapter

  • There are two ways to set up the Adapter of V - Layout:

    1. Inherited from Delegate Adapter

      This is the main way to demonstrate it here.

    2. Inheritance from Virtual Layout Adapter
  • Specific use

MyAdapter.java

public class MyAdapter extends DelegateAdapter.Adapter<MyAdapter.MainViewHolder> {
    // The first thing to do with Delegate Adapter is to customize its internal class Adapter so that LayoutHelper and the data that needs to be bound can be passed in.
    // The Adapter defined here differs only one onCreateLayoutHelper() method from the ordinary RecyclerView Adapter, and the rest is the same.

    private ArrayList<HashMap<String, Object>> listItem;
    // Used to store data lists

    private Context context;
    private LayoutHelper layoutHelper;
    private RecyclerView.LayoutParams layoutParams;
    private int count = 0;

    private MyItemClickListener myItemClickListener;
    // Used to set Item click events

    //Constructor (the number of Item s shown in each data list passed in)
    public MyAdapter(Context context, LayoutHelper layoutHelper, int count, ArrayList<HashMap<String, Object>> listItem) {
        this(context, layoutHelper, count, new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 300), listItem);
    }

    public MyAdapter(Context context, LayoutHelper layoutHelper, int count, @NonNull RecyclerView.LayoutParams layoutParams, ArrayList<HashMap<String, Object>> listItem) {
        this.context = context;
        this.layoutHelper = layoutHelper;
        this.count = count;
        this.layoutParams = layoutParams;
        this.listItem = listItem;
    }

    // Layout of binding ViewHolder to Item
    @Override
    public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new MainViewHolder(LayoutInflater.from(context).inflate(R.layout.item, parent, false));
    }

    // The Adapter defined here differs only one onCreateLayoutHelper() method from the ordinary RecyclerView Adapter
    @Override
    public LayoutHelper onCreateLayoutHelper() {
        return layoutHelper;
    }

    // Data bound to Item
    @Override
    public void onBindViewHolder(MainViewHolder holder, int position) {
        holder.Text.setText((String) listItem.get(position).get("ItemTitle"));
        holder.image.setImageResource((Integer) listItem.get(position).get("ItemImage"));

    }

    // Number of Item s returned
    @Override
    public int getItemCount() {
        return count;
    }

    // Setting Item Click Events
    // Bind the click listener that comes in from MainActivity
    public void setOnItemClickListener(MyItemClickListener listener) {
        myItemClickListener = listener;
    }


    //Define Viewholder
    class MainViewHolder extends RecyclerView.ViewHolder {
        public TextView Text;
        public ImageView image;

        public MainViewHolder(View root) {
            super(root);

            // Binding view
            Text = (TextView) root.findViewById(R.id.Item);
            image = (ImageView) root.findViewById(R.id.Image);

            root.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (myItemClickListener != null)
                        myItemClickListener.onItemClick(v, getPosition());
                }

            }
            //Callback to MainActivity's onItemClick function on listening to clicks
            );

        }

        public TextView getText() {
            return Text;
        }
    }
}

The following steps will be written in the same. Java file

Step 5: Create RecyclerView & VirtualLayoutManager objects and bind them
Step 6: Set the recycle reuse pool size
Step 7: Set up the data to be stored
Step 8: Create the corresponding Layout Helper based on the data list
Step 9: Give the generated LayoutHelper to the Adapter and bind it to the RecyclerView object

See the notes for details.

MainActivity.java

public class MainActivity extends AppCompatActivity implements MyItemClickListener {
    RecyclerView recyclerView;
    MyAdapter Adapter_linearLayout,Adapter_GridLayout,Adapter_FixLayout,Adapter_ScrollFixLayout
            ,Adapter_FloatLayout,Adapter_ColumnLayout,Adapter_SingleLayout,Adapter_onePlusNLayout,
            Adapter_StickyLayout,Adapter_StaggeredGridLayout;
    private ArrayList<HashMap<String, Object>> listItem;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /**
         * Step 1: Create RecyclerView & VirtualLayoutManager objects and bind them
         * */
        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        // Create RecyclerView objects

        VirtualLayoutManager layoutManager = new VirtualLayoutManager(this);
        // Create a VirtualLayoutManager object
        // At the same time, a LayoutHelperFinder object is created internally for subsequent LayoutHelper lookups.

        recyclerView.setLayoutManager(layoutManager);
        // Binding Virtual Layout Manager to recyclerView

        /**
         * Step 2: Setting up a component reuse recycling pool
         * */
        RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
        recyclerView.setRecycledViewPool(viewPool);
        viewPool.setMaxRecycledViews(0, 10);

        /**
         * Step 3: Set up the data to be stored
         * */
        listItem = new ArrayList<HashMap<String, Object>>();
        for (int i = 0; i < 100; i++) {
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("ItemTitle", "The first" + i + "That's ok");
            map.put("ItemImage", R.mipmap.ic_launcher);
            listItem.add(map);

        }

        /**
         * Step 4: Create the corresponding Layout Helper based on the data list
         * */

        // To show the effect, all the layouts described above are shown here.

        /**
         Setting up Linear Layout
         */
        LinearLayoutHelper linearLayoutHelper = new LinearLayoutHelper();
        // Create the corresponding LayoutHelper object

        // Public attribute
        linearLayoutHelper.setItemCount(4);// Set the number of Item s in the layout
        linearLayoutHelper.setPadding(20, 20, 20, 20);// Set the distance between the child elements of LayoutHelper and the edge of LayoutHelper
        linearLayoutHelper.setMargin(20, 20, 20, 20);// Set the distance between the LayoutHelper edge and the parent control (RecyclerView)
        // Linear Layout Helper. setBgColor (Color. GRAY); // Set background color
        linearLayoutHelper.setAspectRatio(6);// Set the ratio of width to height for each line layout in the layout

        // linearLayoutHelper's unique attributes
        linearLayoutHelper.setDividerHeight(10);
        // Set interval height
        // The interval set is superimposed with the interval added by addItemDecoration () of RecyclerView.

        linearLayoutHelper.setMarginBottom(100);
        // Set the interval between the bottom of the layout and the next layout


        // Create a custom Adapter object-bound data-bind the corresponding LayoutHelper for layout drawing
         Adapter_linearLayout  = new MyAdapter(this, linearLayoutHelper, 4, listItem) {
             // Parametric 2: LayoutHelper corresponding to the binding
             // Parametric 3: Number of data to be displayed in the incoming layout
             // Parametric 4: Pass in data that needs to be bound

             // Set up richer layout effects by rewriting onBindViewHolder()
             @Override
             public void onBindViewHolder(MainViewHolder holder, int position) {
                 super.onBindViewHolder(holder, position);
                 // To show the effect, set the first data of the layout to linearLayout
                 if (position == 0) {
                     holder.Text.setText("Linear");
                 }

                  //In order to show the effect, Item in different locations in the layout is used to set the background color.
                 if (position < 2) {
                     holder.itemView.setBackgroundColor(0x66cc0000 + (position - 6) * 128);
                 } else if (position % 2 == 0) {
                     holder.itemView.setBackgroundColor(0xaa22ff22);
                 } else {
                     holder.itemView.setBackgroundColor(0xccff22ff);
                 }

             }
         };

        Adapter_linearLayout.setOnItemClickListener(this);
        // Set click events for each Item

        ....// There are other layouts that are not posted because of the large amount of code.

        /**
         *Step 5: Give the generated LayoutHelper to the Adapter and bind it to the RecyclerView object
         **/

        // 1. Set the Adapter List (and also the LayoutHelper List)
        List<DelegateAdapter.Adapter> adapters = new LinkedList<>();

        // 2. Put the created adapter object in the DelegateAdapter.Adapter list
        adapters.add(Adapter_linearLayout) ;
        adapters.add(Adapter_StickyLayout) ;
        adapters.add(Adapter_ScrollFixLayout) ;
        adapters.add(Adapter_GridLayout) ;
        adapters.add(Adapter_FixLayout) ;
        adapters.add(Adapter_FloatLayout) ;
        adapters.add(Adapter_ColumnLayout) ;
        adapters.add(Adapter_SingleLayout) ;
        adapters.add(Adapter_onePlusNLayout) ;
        adapters.add(Adapter_StaggeredGridLayout) ;

        // 3. Create DelegateAdapter Objects & Bind Layout Manager to DelegateAdapter
        DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager);

        // 4. Bind the Delegate Adapter. Adapter list to Delegate Adapter
        delegateAdapter.setAdapters(adapters);

        // 5. Bind delegate adapter to recyclerView
        recyclerView.setAdapter(delegateAdapter);


        /**
         *Step 6: Interval between Items
         **/

        recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                outRect.set(5, 5, 5, 5);
            }
        });


    }

    /**
     *Step 7: Implement Item Click Event
     **/
    // Click event callback function
    @Override
    public void onItemClick(View view, int postion) {
        System.out.println("Click the first"+postion+"That's ok");
        Toast.makeText(this, (String) listItem.get(postion).get("ItemTitle"), Toast.LENGTH_SHORT).show();
    }
}

Design sketch


Total effect map

Source address

Github address of Carson_Ho: V - Layout

Reference documents:
https://github.com/alibaba/vlayout
http://pingguohe.net/2017/02/28/vlayout-design.html

7. summary

  • After reading this article, you should have a good understanding of the use of V - Layout produced by Ali
  • But there are still many small Bug s in the open source library. I also submitted some on Github. I hope you can join us in the Github - alibaba - vlayout Perfect and contribute to the cause of open source together! uuuuuuuuuuuu
  • Next, I'll continue to analyze Android's other excellent open source libraries in detail, which I'm interested in continuing to focus on. Carson_Ho's Notes on Android Development

Please praise! Because your encouragement is my greatest motivation to write!

Reading Related Articles
Android development: the most comprehensive and understandable Android screen adaptation solution
Android Event Distribution Mechanisms: The Most Comprehensive and Easiest to Understand in History
Android Development: The Most Complete Android Message Push Solution in History
Android development: the most comprehensive and understandable Web view in detail
Android development: JSON profile and the most comprehensive parsing method!
Four components of Android: the most comprehensive analysis in Service history
Four components of Android: the most comprehensive analysis in the history of Broadcast Receiver

Welcome to your attention. Carson_Ho The short book!

Share dried products about Android development from time to time, pursuing short, flat and fast, but without lack of depth.


Posted by watsonowen on Sun, 16 Dec 2018 12:36:04 -0800