Android-使用FlexboxLayout輕松實現流式布局


產品需求:

1.列表篩選顯示標簽,標簽按文本長度展示,不固定長度,當長度最大為168時顯示省略

2.2行以內全部展示,超過2行,只展示2行;點擊展開,展示2行及以上,點擊收起,展示2行。

 

按照以往實現方式,直接使用recylerview設置布局方式為Gridview,然后扒拉扒拉一頓寫,發現完全不合要求。

實現技術難點:

長度不固定、高度不固定。

然后了解到google出了一個布局控件,引入flexlayout,完美解決。

 

FlexboxLayout:

 

FlexboxLayout是去年 Google I/O 上開源的一個布局控件,FlexboxLayout可以理解為高級的linearLayout,它提供了FlexboxLayoutManager,可以輕松實現子布局換行顯示。

 

使用

 項目中添加依賴:

 //流式布局
    implementation 'com.google.android:flexbox:1.0.0'

簡單實現

創建FlexboxLayoutManager,並為recylerview設置layoutManager。

  //設置流式布局
        flexboxLayoutManager = new FlexboxLayoutManager(mActivity); flexboxLayoutManager.setFlexWrap(FlexWrap.WRAP); //設置是否換行
        flexboxLayoutManager.setFlexDirection(FlexDirection.ROW); // 設置主軸排列方式
 flexboxLayoutManager.setAlignItems(AlignItems.STRETCH); flexboxLayoutManager.setJustifyContent(JustifyContent.FLEX_START);  rvCondition.setLayoutManager(flexboxLayoutManager);

recylerview子布局。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="@color/_F4F8FF"
    android:layout_marginRight="10dp"
    android:layout_marginBottom="10dp"
    android:id="@+id/ll_layout"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/tv_condition"
       style="@style/textviewCommonStyle"
        android:layout_width="wrap_content"
        android:layout_height="28dp"
        android:ellipsize="end"
        android:layout_weight="1"
        android:maxWidth="168dp"
        android:textSize="13sp"
        android:textColor="@color/_001A37"
        android:maxLines="1"
        tools:text="奧迪A3 2019款Limousine 35 TFSI 運動型 國 VI11111111111111111111111111111111111"
        android:paddingLeft="8dp"
        android:gravity="center_vertical"
        android:paddingTop="0dp"
        android:paddingBottom="0dp"
        android:paddingEnd="0dp"
        />

    <ImageView
        android:id="@+id/iv_delete"
        android:layout_width="18dp"
        android:layout_height="24dp"
        android:paddingEnd="8dp"
        android:paddingTop="8dp"
        android:paddingBottom="8dp"
        android:paddingStart="2dp"
        android:src="@drawable/ic_delete2"
        android:layout_gravity="end|center_vertical"/>
</LinearLayout>

流式布局是實現了,現在的問題是怎么獲取高度來判斷當前行數呢

這里我是通過recylerview的最后一個item展示來判斷,通過行數來設置當前recylerview的高度。

private void setCurMode(int layoutPosition, View itemView) {
        if(layoutPosition != conditionList.size() -1) return;
        itemView.post(new Runnable() {
            @Override
            public void run() {
                //判斷當前顯示幾行
                Log.e("fg","繪制完畢");
                lines = Math.ceil(rvCondition.getHeight() / DeviceUtils.dpToPixel(mActivity, 38));
                Log.e("fg","當前行數--"+lines);
                if(lines <= 1){
                    tvClose.setVisibility(View.GONE);
                    tvClearAll.setVisibility(View.GONE);
                }else if(lines == 2){
                    isClosed = true;
                    tvClose.setVisibility(View.GONE);
                    tvClearAll.setVisibility(View.VISIBLE);
                }else if(lines >= 3){
                    if(isClosed) {
                        tvClose.setVisibility(View.VISIBLE);
                        tvClose.setText("展開");
                        tvClearAll.setVisibility(View.GONE);
                    }else{
                        tvClose.setVisibility(View.VISIBLE);
                        tvClose.setText("收起");
                        tvClearAll.setVisibility(View.VISIBLE);
                    }
                }
                setCurLabelHeight(!isClosed);
            }
        });
    }
setCurLabelHeight()
  private void setCurLabelHeight(boolean isOpen) {
        ViewGroup.LayoutParams layoutParams = rvCondition.getLayoutParams();
        if(!isOpen && lines >= 2){
            //收縮 設置為2行
            layoutParams.height = DeviceUtils.dpToPixel(mActivity,38 * 2);
        }else{
            //展開,設置為包裹
            layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
        }
        rvCondition.setLayoutParams(layoutParams);
    }

實現效果:

 

某人說這樣顯示不好,每次操作一個刪除或者添加標簽時,都會去重置recylerview的高度后,再設置一次recyclerview的布局,后續操作的話換一種思路實現。
通過按鈕點擊監聽來判斷當前是否可折疊,再折疊,同理,先判斷是否可展開再展開。
1.當前是否可折疊。
 //是否可以折疊
    private boolean canFold() {
        return Math.ceil(layoutManager.getHeight() / dp2px(40)) > 2;
    }
2.當前是否可展開。
  //是否可以展開
    private boolean canOpen() {
        return layoutManager.findLastVisibleItemPosition() != list.size() -1;
    }

 相關參考:

1.https://www.jianshu.com/p/12da0a7db962

2.https://www.jianshu.com/p/b3a9c4a99053


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM