1. Introduction

A few days ago, I saw Google’s official blog introducing FlexboxLayout, a powerful layout for Google open source. When I first saw it, I thought, Oh my God, Android has such a powerful layout. As a curious engineering lion, of course, the first time to try, the effect is very good, so this article will introduce its usage and the latest version of the added some features (support integration RecyclerView),Github address: github.com/google/flex… . The contents of this article are as follows:

PNG

2. What is FlexboxLayout

So what exactly is 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.

3. FlexboxLayout example

FlexboxLayout is easy to use, but it’s not easy to use. It’s easy to use, and it’s easy to use. It’s easy to use. The hot topics on the front page of the book are as follows:

PNG


FlexboxLayout.png

Add dependencies:

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

The code is as follows:

<? The XML version = "1.0" encoding = "utf-8"? > <com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/flexbox_layout" app:flexWrap="wrap" app:alignItems="center" app:alignContent="flex_start" app:flexDirection="row" app:justifyContent="flex_start" app:showDivider="beginning|middle" app:dividerDrawable="@drawable/divider_shape" > <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" android:background="@drawable/label_bg_shape" /> <TextView android:layout_width="wrap_content" android:layout_height="40dp" android:paddingLeft="15dp" android:paddingRight="15dp" app:layout_alignSelf="flex_start" Android :text=" @color/text_color" app:layout_flexGrow="1" Android :gravity="center" Android :textColor="@color/text_color" android:background="@drawable/label_bg_shape" /> <TextView android:layout_width="wrap_content" android:layout_height="40dp" android:paddingLeft="15dp" android:paddingRight="15dp" app:layout_flexGrow="1" App :layout_alignSelf="flex_start" Android :text=" gourmet "Android :gravity="center" Android :textColor="@color/text_color" android:background="@drawable/label_bg_shape" /> <TextView android:layout_width="wrap_content" android:layout_height="40dp" android:paddingLeft="15dp" android:paddingRight="15dp" app:layout_flexGrow="1" App :layout_alignSelf="flex_start" Android :text=" manga. Gravity =" gravity "android:gravity="center" Android :background="@drawable/label_bg_shape" /> <TextView android:layout_width="wrap_content" android:layout_height="40dp" android:paddingLeft="15dp" Android :paddingRight="15dp" app:layout_alignSelf="flex_start" Android :text=" AD circle "Android :gravity="center" android:textColor="@color/text_color" android:background="@drawable/label_bg_shape" /> <TextView android:layout_width="wrap_content" android:layout_height="40dp" android:paddingLeft="15dp" android:paddingRight="15dp" App :layout_alignSelf="flex_start" Android :text=" travel. "Android :gravity="center" Android :textColor="@color/text_color" Android :background="@drawable/label_bg_shape" /> <TextView android:layout_width="wrap_content" android:layout_height="40dp" android:paddingLeft="15dp" Android :paddingRight="15dp" app:layout_alignSelf="flex_start" Android :text=" gravity "Android :gravity="center" android:textColor="@color/text_color" android:background="@drawable/label_bg_shape" /> <TextView android:layout_width="wrap_content" android:layout_height="40dp" android:paddingLeft="15dp" android:paddingRight="15dp" App :layout_alignSelf="flex_start" Android :text=" youth "Android :gravity="center" Android :textColor="@color/text_color" android:background="@drawable/label_bg_shape" /> <TextView android:layout_width="wrap_content" android:layout_height="40dp" android:paddingLeft="15dp" android:paddingRight="15dp" app:layout_alignSelf="flex_start" Android :gravity="center" Android :textColor="@color/text_color" android:background="@drawable/label_bg_shape" /> <TextView android:layout_width="wrap_content" android:layout_height="40dp" android:paddingLeft="15dp" android:paddingRight="15dp" app:layout_alignSelf="flex_start" Android :text=" gravity="center" Android :textColor="@color/text_color" android:background="@drawable/label_bg_shape" /> <TextView android:layout_width="wrap_content" android:layout_height="40dp" android:paddingLeft="15dp" android:paddingRight="15dp" app:layout_alignSelf="flex_start" Android :text=" "Android :gravity="center" Android :textColor="@color/text_color" android:background="@drawable/label_bg_shape" /> <TextView android:layout_width="wrap_content" android:layout_height="40dp" android:paddingLeft="15dp" android:paddingRight="15dp" app:layout_alignSelf="flex_start" Android :text=" gravity "android:gravity="center" Android :textColor="@color/text_color" android:background="@drawable/label_bg_shape" /> </com.google.android.flexbox.FlexboxLayout>Copy the code

Very simple, just a layout file, with FlexboxLayout as the parent layout, and add child items to the container. Of course, you can add child elements to the FlexboxLayout dynamically in code like this:

        mFlexboxLayout = (FlexboxLayout) findViewById(R.id.flexbox_layout);

        // Add a View to FlexboxLayout with code
        TextView textView = new TextView(this);
        textView.setBackground(getResources().getDrawable(R.drawable.label_bg_shape));
        textView.setText("Test Label");
        textView.setGravity(Gravity.CENTER);
        textView.setPadding(30.0.30.0);
        textView.setTextColor(getResources().getColor(R.color.text_color));
        mFlexboxLayout.addView(textView);
        / / by FlexboxLayout. LayoutParams set properties for child support
        ViewGroup.LayoutParams params = textView.getLayoutParams();
        if(params instanceof FlexboxLayout.LayoutParams){
            FlexboxLayout.LayoutParams layoutParams = (FlexboxLayout.LayoutParams) params;
            layoutParams.setFlexBasisPercent(0.5 f);
        }Copy the code

If you don’t use FlexboxLayout, you need to customize the View to achieve such an interface, or a bit of trouble, there are many online through the custom View to achieve a scalable interface, you can search for it. This is just the tip of the iceberg for FlexboxLayout. The real power of FlexboxLayout is the properties it defines. You can set different values to achieve different effects.

4. Properties supported by FlexboxLayout

FlexboxLayout defines properties that are truly powerful. In this section, we will take a look at the properties supported by Flexbox. The properties supported by FlexboxLayout and the properties supported by FlexboxLayout child elements are divided into two categories:

FlexboxLayout supports the following 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.

    The text is a bit weak, but look at the comparison of the four permutations:

Paste_Image.png

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 alignment
  • Center: center
  • Space_between: both ends are aligned with the same spacing
  • Space_around: Each element is equidistant 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 aligned
  • Center: center
  • Baseline: baseline alignment of the first line.

The text display is a bit weak, so let’s compare it with a picture (from FlexboxLayout) :

AlignItems.png

alignContent

The alignContent property controls the alignment of multiple axes (i.e., multiple lines, not 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.
showDividerHorizontal

ShowDividerHorizontal control displays a horizontal line, value to none | beginning | middle | end one or more of them.

dividerDrawableHorizontal

DividerDrawableHorizontal set between Flex axis horizontal line.

showDividerVertical

ShowDividerVertical control according to vertical line, value to none | beginning | middle | end one or more of them.

dividerDrawableVertical

DividerDrawableVertical Sets the vertical dividing line for the child element.

showDivider

ShowDivider control show that the horizontal and vertical direction line, a value of none | beginning | middle | end one or more of them.

dividerDrawable

DividerDrawable sets the horizontal and vertical dividing lines, but note that if used with other attributes, For example, the Flex axis, child elements were set to Justify yContent=”space_around”, alignContent=”space_between”, etc. You may see unexpected Spaces, so you should avoid using them in conjunction with these values.

5. The attributes supported by the FleboxLayout child element

The FlexboxLayout child element supports the following attributes:

layout_order

The layout_order attribute changes the order in which the child elements are arranged. By default, the FlexboxLayout child elements are arranged in the order they appear in the XML file. The default value is 1. The smaller the value, the higher the rank.

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_flexShrink(float)

The default value is 1. If the layout_flexShrink value of all the child elements is 1, the child elements shrink equally if the space is insufficient. If one of the child elements is 0 and the others are 1, the child elements shrink equally if the space is insufficient. 0 does not shrink, and negative values are invalid.

layout_alignSelf

The layout_alignSelf property sets the alignment of child elements. The alignItems property above sets the alignment. This property does the same thing as alignItems, except alignItems applies to all child elements. Layout_alignSelf applies to a single child element. The default value is auto, which inherits the alignItems property, or a value other than auto overrides the alignItems property. There are six values:

  • auto (default)
  • flex_start
  • flex_end
  • center
  • baseline
  • stretch

Same as the alignItems property except auto.

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.

layout_minWidth / layout_minHeight (dimension)

Force FlexboxLayout to limit its child elements (width or height) to no less than the minimum. Regardless of the value of the layout_flexShrink attribute, the child elements will not be reduced to less than the set minimum.

layout_maxWidth / layout_maxHeight (dimension)

This is the reverse of the above, forcing the FlexboxLayout child element to be no larger than this maximum, regardless of the layout_flexGrow value, the child element will not be larger than this maximum.

layout_wrapBefore

The layout_wrapBefore attribute controls forcing line breaks. The default value is false. If this attribute is set to true, a child element will be the first element in the line. This property ignores the noWrap value set by flex_wrap.

6. Combination with RecyclerView

In the latest alpha, Flexbox can be used as a LayoutManager in RecyclerView, which means you can use Flexbox in a scrollable container with a large number of items.

Here’s an example of how to use inherited RecyclerView:

(1) First rely on the latest alpha release, as follows:

/ / the compile 'com. Google. Android: flexbox: 0.2.5'
 // Use the latest alpha version
    compile 'com. Google. Android: flexbox: 0.3.0 - alpha2'Copy the code

(2) Use FlexboxLayoutManager instead of LinearLayoutManager, as follows:

 FlexboxLayoutManager manager = new FlexboxLayoutManager();
 // Set the spindle arrangement
 manager.setFlexDirection(FlexDirection.ROW);
 // Sets whether to break a line
 manager.setFlexWrap(FlexWrap.WRAP);
 manager.setAlignItems(AlignItems.STRETCH);Copy the code

(3) Set flexGrow in Adapter:

 ImageView mImageView =  rvBaseViewHolder.getImageView(R.id.image_src);
       mImageView .setImageResource(mData);

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

The renderings are as follows:

FlexboxLayoutManager.gif

Isn’t it powerful? Effect is similar to waterfall flow, but waterfall flow is specified the number of columns, this is completely custom newline, size screen adaptation completely solved, it is perfect. However, the current integration with RecyclerView is still the alpha version, which has not been merged into the Master branch. I believe that a stable version will come out soon.

Some properties of Flexbox are not implemented in FlexboxLayoutManager due to some RecyclerView features. Here is a comparison of properties supported by FlexboxLayout and FlexboxLayoutManager:

Similarities and differences of supported attributes. PNG

Note the properties circled in the red box. FlexboxlayoutManager supports View recycling. FlexboxLayout does not support View recycling. That’s where FlexboxLayoutManager comes in.

7. To summarize

FlexboxLayout is a powerful layout that Google opened last year. It has a similar function to CSS Flexbox. It has a newline feature and is very convenient to use. However,FlexboxLayout does not consider View recycling. Adding a large number of items to it will cause memory overflow. Fortunately, the latest version added and RecyclerView integration, which can be used in the context of a large quantum Item, but the latest version is still alpha version, there is no stable version, I believe that will soon be able to use a stable version. In addition, the meaning of the properties in FlexboxLayout can be difficult to understand. I recommend you to write a demo to try each value of each property to see how it works. This will help you understand each property.

Someone said Demo was needed in the comments section, so I uploaded it to Github, please stampFlexboxLayout Demo

Reference:

Github.com/google/flex… Build Flexible layouts with FlexboxLayout for Android