1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Android仿淘寶搜索歷史界面功能

        共 7131字,需瀏覽 15分鐘

         ·

        2021-08-03 19:12

        一 關(guān)于自定義viewGroup

        自定義viewGroup需要繼承viewGroup,并重寫抽象方法onLayout,
        負責(zé)子view位置的擺放。onMeasure()方法則完成對子view的測量過程,
        其中,對子view的測量涉及到MeasureSpec,包括父布局的MeasureSpec
        和子view的MeasureSpec。對子view的寬高測量完成后,相加即為
        viewGroup的寬高,再通過setMeasuredDimension()
        這個方法來保存測量好的寬高。

        二 關(guān)于MeasureSpec

        MeasureSpec代表一個32位int值,高2位代表SpecMode,低30位代碼SpecSize,SpecMode是指測量模式,而SpecSize是指在某種測量模式下地規(guī)格地大小。

        SpecMode有三類,每一類都表示特殊的含義,如下所示。

        UNSPECIFIED
        父容器不對View有任何限制,要多大給多大,這種情況一般用于系統(tǒng)內(nèi)部,表示一種測量狀態(tài)。

        EXACTLY
        父容器以及檢測出View所需要的大小,這個時候View的最終大小就是SpecSize所指定的值。它對應(yīng)于LayoutParams中的match_parent和具體數(shù)值這兩種模式。

        AT_MOST
        父容器指定了一個可用大小即SpecSize,View的大小不能大于這個值,具體是什么要看不同View的具體實現(xiàn)。它對應(yīng)于LayoutParams中的wrap_content。


        三 關(guān)于流式布局Measure流程


        1.遍歷所有的子view,根據(jù)父布局的MeasureSpec還有子view的
        LayoutParams 算出子view的MesureSpec

        LayoutParams childLP = childView.getLayoutParams();
        int childWidthMesureSpec =getChildMeasureSpec(widthMeasureSpec,paddingLeft+paddingRight,childLP.width);
        int childHeightMesureSpec =getChildMeasureSpec(heightMeasureSpec,paddingBottom+paddingTop,childLP.height);
        childView.measure(childWidthMesureSpec,childHeightMesureSpec);

        2.通過寬度來判斷是否需要換行,通過換行后的每行的行高來獲取整個viewGroup的行高
        如果寬度不夠,則需換行

        if (childMesuredWidth + lineWidthUsed +mHorizontalSpacing > selfWidth){
        allLines.add(lineViews);
        lineHeights.add(lineHeight);
        //一旦換行,可以判斷當(dāng)前所需的寬高了
        parentNeededWidth = Math.max(parentNeededWidth,lineWidthUsed+mHorizontalSpacing);
        parentNeededHeight = parentNeededHeight + lineHeight +mVerticalSpacing;
        lineViews =new ArrayList<>();
        lineWidthUsed =0;
        lineHeight =0;
        }

        3.根據(jù)子View的度量結(jié)果,來重新度量自己ViewGroup
        作為一個ViewGroup,它自己也是一個View,它的大小也需要根據(jù)它的父親給它提供的寬高來度量

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int realWidth = (widthMode == MeasureSpec.EXACTLY)? selfWidth:parentNeededWidth;
        int realHeight = (heightMode == MeasureSpec.EXACTLY)?selfHeight:parentNeededHeight;
        setMeasuredDimension(realWidth,realHeight);

        四 關(guān)于layout流程

        measure完成后,每個子view的寬高通過view.getMeasuredHeight/Width 
        來獲得,只需算出距離viewGroup左邊和頂部的距離傳入即可。

        int lineCount =allLines.size();
        int curL =0;
        int curT =0;
        for (int i =0;i
        List lineViews =allLines.get(i);
        int lineHeight =lineHeights.get(i);
        for (int j =0;j
        View view = lineViews.get(j);
        int left = curL;
        int top = curT;
        int bottom = top + view.getMeasuredHeight();
        int right = left + view.getMeasuredWidth();
        view.layout(left,top,right,bottom);
        curL = right +mHorizontalSpacing;
        }
        curL =0;
        curT = curT + lineHeight +mVerticalSpacing;

        五 關(guān)于源代碼FlowLayout源代碼
        public class FlowLayoutextends ViewGroup {
        private int mHorizontalSpacing =dp2px(16); //每個item橫向間距
        private int mVerticalSpacing =dp2px(8); //每個item橫向間距
        private List>allLines ; // 記錄所有的行,一行一行的存儲
        private ListlineHeights =new ArrayList<>(); // 記錄每一行的行高
        boolean isMeasuredOver =false;
        public FlowLayout(Context context) {
        super(context);
        }
        public FlowLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        }
        public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        }
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        initMeasureParams();
        int childCount = getChildCount();
        int paddingLeft = getPaddingLeft();
        int paddingRight = getPaddingRight();
        int paddingTop = getPaddingTop();
        int paddingBottom = getPaddingBottom();
        int selfWidth = MeasureSpec.getSize(widthMeasureSpec); //ViewGroup解析的寬度
        int selfHeight = MeasureSpec.getSize(heightMeasureSpec); // ViewGroup解析的高度
        List lineViews =new ArrayList<>(); //保存一行中的所有的view
        int lineWidthUsed =0; //記錄這行已經(jīng)使用了多寬的size
        int lineHeight =0; // 一行的行高
        int parentNeededWidth =0; // measure過程中,子View要求的父ViewGroup的寬
        int parentNeededHeight =0; // measure過程中,子View要求的父ViewGroup的高
        for (int i =0;i
        View childView = getChildAt(i);
        LayoutParams childLP = childView.getLayoutParams();
        int childWidthMesureSpec =getChildMeasureSpec(widthMeasureSpec,paddingLeft+paddingRight,childLP.width);
        int childHeightMesureSpec =getChildMeasureSpec(heightMeasureSpec,paddingBottom+paddingTop,childLP.height);
        childView.measure(childWidthMesureSpec,childHeightMesureSpec);
        //獲取子view的寬高
        int childMesuredWidth = childView.getMeasuredWidth();
        int childMesuredHeight = childView.getMeasuredHeight();
        //通過寬度來判斷是否需要換行,通過換行后的每行的行高來獲取整個viewGroup的行高
        //如果寬度不夠,則需換行
        if (childMesuredWidth + lineWidthUsed +mHorizontalSpacing > selfWidth){
        allLines.add(lineViews);
        lineHeights.add(lineHeight);
        //一旦換行,可以判斷當(dāng)前所需的寬高了
        parentNeededWidth = Math.max(parentNeededWidth,lineWidthUsed+mHorizontalSpacing);
        parentNeededHeight = parentNeededHeight + lineHeight +mVerticalSpacing;
        lineViews =new ArrayList<>();
        lineWidthUsed =0;
        lineHeight =0;
        }
        // view 是分行l(wèi)ayout的,所以要記錄每一行有哪些view,這樣可以方便layout布局
        lineViews.add(childView);
        lineWidthUsed = lineWidthUsed + childMesuredWidth +mHorizontalSpacing;
        lineHeight = Math.max(lineHeight,childMesuredHeight);
        //childview 最后一行
        if (i == childCount -1){
        lineHeights.add(lineHeight);
        allLines.add(lineViews);
        parentNeededWidth = Math.max(parentNeededWidth,lineWidthUsed );
        parentNeededHeight += lineHeight;
        }
        //根據(jù)子View的度量結(jié)果,來重新度量自己ViewGroup
        // 作為一個ViewGroup,它自己也是一個View,它的大小也需要根據(jù)它的父親給它提供的寬高來度量
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int realWidth = (widthMode == MeasureSpec.EXACTLY)? selfWidth:parentNeededWidth;
        int realHeight = (heightMode == MeasureSpec.EXACTLY)?selfHeight:parentNeededHeight;
        setMeasuredDimension(realWidth,realHeight);
        isMeasuredOver =true;
        }
        }
        private void initMeasureParams() {
        allLines =new ArrayList<>();
        lineHeights =new ArrayList<>();
        }
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int lineCount =allLines.size();
        int curL =0;
        int curT =0;
        for (int i =0;i
        List lineViews =allLines.get(i);
        int lineHeight =lineHeights.get(i);
        for (int j =0;j
        View view = lineViews.get(j);
        int left = curL;
        int top = curT;
        int bottom = top + view.getMeasuredHeight();
        int right = left + view.getMeasuredWidth();
        view.layout(left,top,right,bottom);
        curL = right +mHorizontalSpacing;
        }
        curL =0;
        curT = curT + lineHeight +mVerticalSpacing;
        }
        }
        public static int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().getDisplayMetrics());
            }}

        六 項目運行截圖


        源碼地址:
        (https://github.com/doubizhu/flowlayout)

        到這里就結(jié)束啦。
        瀏覽 186
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            综合色吧 | 亚洲热视频在线 | 欧美精品一级 | 欧美三级黄色大片 | 婷婷色在线观看 | 无遮挡无掩盖的网站 | 日韩成人精品一区二区 | 女人高潮叫床骚话污话 | 成人网站免费大全日韩国产 | 久久久九九 |