One of the cool layouts I saw earlier is FlexboxLayout, which makes it easy to create waterfall streams. Today is a good time to use FlexboxLayout for a simple study.

First, the effect drawing

Let’s start with a wave of renderings.





Familiar, right? It’s a custom popular page for Jane books. Through today’s learning, the use of FlexboxLayout+RecyclerView can be achieved.

The following is the effect of their own implementation:









Application scenarios like the one above are often seen in some apps. So learn and see how it works.

FlexboxLayout

FlexboxLayout is a library project which brings the similar capabilities of CSS Flexible Box Layout Module to Android.

FlexboxLayout is an Android library that has similar functionality to CSS’s Flexible Box layout module. Flexbox is a CSS layout solution that can easily and quickly implement complex layouts. FlexboxLayout can be understood as an advanced LinearLayout, because both layouts arrange the child views in order. The biggest difference between the two is that FlexboxLayout has line breaks.

FlexboxLayout is an open source layout for Google. If you are good at English, you can directly see the details of its properties.

Of course, you can also see some translation of the introduction of FlexboxLayout, such as: Android scalable layout -FlexboxLayout(support RecyclerView integration), introduced very clear.

Important properties of FlexboxLayout

Here are just a few of the commonly used FlexboxLayout properties.

flexDirection:

The flexDirection property determines the direction of the main axis, that is, the arrangement direction of the child items in FlexboxLayout. There are four values:

Row (default) : the default value. The main axis is horizontal from left to right. Row_reverse: The main axis is horizontal, the starting point is at the end, and it runs from right to left. Column: The main axis is in the vertical direction, and the starting point is at the top and runs from top to bottom. Column_reverse: The main axis is vertical and the start point is at the bottom and upward.





flexWrap

The flexWrap property determines whether the Flex container is single-row or multi-row and determines the direction of the secondary axis (the axis perpendicular to the main axis). There are three possible values:

NoWrap: Displays the child element on one line without a newline. Wrap: Wrap the line in the normal direction. Wrap_reverse: Newlines in the opposite direction.





justifyContent

The justifyContent attribute controls the alignment of elements in the main axis. It has the following five values:

Flex_start (default): default value, left-aligned flex_end: right-aligned Center: centered space_BETWEEN: aligned at both ends with the same spacing space_around: each element has the same distance from both sides.





alignItems

The alignItems property controls the alignment of elements along the secondary axis. There are five values:

Stretch (default) : the default value. If item does not set the height, it will fill the container height. Flex_start: top alignment FLEX_END: bottom alignment Center: center alignment baseline: baseline alignment of the first line





alignContent

The alignContent property controls the alignment of multiple axes (i.e., multiple lines, which does not work if the child element has only one line) and can have the following six values:

Stretch (default): the default value, full height of the cross axis (test found that the value of alignItems is also “stretch” to be valid). Flex_start: Aligned with the cross axis starting point. Flex_end: Aligns with the cross axis endpoint. Center: center aligned with the cross axis. Space_between: Cross axes are aligned at both ends with equal intervals. Space_around: Equidistant from both ends of the intersecting axis.





Important properties supported by the FleboxLayout child element

Here are some important attributes supported by child elements

layout_flexGrow(float)

The size of the layout_flexGrow child element, which determines how to allocate free space (if any). The default value is 0. No free space is allocated. The remaining space will be allocated to this Item. If there are more than one Item whose value is positive, the remaining space will be allocated according to the ratio defined by layout_flexGrow (somewhat like the Layout_weight property of the LinearLayout).

layout_flexBasisPercent (fraction)

The value of layout_flexBasisPercent is a percentage that sets the length of the child element to the length of its parent container. If this value is set, the value calculated from this property overrides either layout_width or layout_height. Note, however, that this value is valid only if the parent container length is set (i.e. MeasureSpec mode is MeasureSpec.EXACTLY). The default value is -1.

FlexboxLayout also has other powerful properties that need to be seen in the previous two articles.

Use FlexboxLayout

1. Add dependencies

compile 'com. Google. Android: flexbox: 0.2.5'Copy the code

2. Specific code

The first way:
Layout file
<? xml version="1.0" encoding="utf-8"? > <com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/flexbox_layout"
    app:flexWrap="wrap"
    app:alignItems="center"
    app:alignContent="flex_start"
    app:flexDirection="row"
    app:justifyContent="flex_start"
    >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        app:layout_alignSelf="flex_start"
        android:text="Programmer"
        android:gravity="center"
        android:textColor="@color/text_color"/ >... </com.google.android.flexbox.FlexboxLayout>Copy the code

You can achieve the waterfall effect by adding multiple child controls to FlexboxLayout. You can also dynamically add child controls to your code to achieve the same effect. However, this situation is not suitable for the scene of too many child views. If there are too many child views, it is recommended to use FlexboxLayout+RecyclerView.

The second way:

The first step is to replace the original dependency and rely on the latest alpha version as follows:

 compile 'com. Google. Android: flexbox: 0.3.0 - alpha2'Copy the code
Layout file
<?xml version="1.0" encoding="utf-8"? >
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="false"
                android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="? attr/actionBarSize"
        android:background="@color/background_material_light_1"
        android:fitsSystemWindows="true">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <ImageView
                android:id="@+id/iv_wrong"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_alignParentLeft="true"
                android:src="@drawable/favor_wrong"/>

            <ImageView
                android:id="@+id/iv_right"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_alignParentRight="true"
                android:paddingRight="10dp"
                android:src="@drawable/favor_right"/>
        </RelativeLayout>


    </android.support.v7.widget.Toolbar>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_favor"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/toolbar">
    </android.support.v7.widget.RecyclerView>
</RelativeLayout>Copy the code

RecyclerView is put into the main layout.

Add content
 mAdapter = new FavorMovieAdapter(list,mContext,mSelectList);
        FlexboxLayoutManager manager = new FlexboxLayoutManager(a);// Set the spindle arrangement
        manager.setFlexDirection(FlexDirection.ROW);
        // Sets whether to break a line
        manager.setFlexWrap(FlexWrap.WRAP);
        mRvFavor.setLayoutManager(manager);
        mRvFavor.setItemAnimator(new DefaultItemAnimator());
        mRvFavor.setAdapter(mAdapter);Copy the code

Through FlexboxLayoutManager as a LayoutManager(FlexboxLayoutManager) used in RecyclerView, to achieve the powerful function of FlexboxLayout.

Set child element attributes in Adapter

Fill the remaining space in each row

ViewGroup.LayoutParams params = holder.mTitle.getLayoutParams();
        if (params instanceof FlexboxLayoutManager.LayoutParams) {
            FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams) holder.mTitle.getLayoutParams();
            flexboxLp.setFlexGrow(1.0f);
        }Copy the code

Five, the summary

FlexboxLayout+RecyclerView can realize the effect of waterfall flow, do not need to specify the number of columns, can realize automatic newline, and FlexboxLayout has a variety of properties, make the form of waterfall flow more flexible. These are just a few simple uses.