分析v7中的LinearLayoutCompat类

来源:互联网 发布:from unixtime mysql 编辑:程序博客网 时间:2024/06/06 17:45
   LinearLayoutCompat是个很神奇的类,在我们写布局的时候我们经常用用view这个空间来画一条线,导致布局中有很多这样的无用布局,但是不写又不符合界面设置规范,用listview来写,条目很少,没必要,各种纠结。让我们来认识下LinearLayoutCompat这个类吧,原生的,带你飞起来,你会有相见恨晚的感觉。

效果图:
这里写图片描述

** <android.support.v7.widget.LinearLayoutCompat        android:layout_width="match_parent"       android:divider="@android:drawable/divider_horizontal_bright"        android:showDividers="middle"        android:orientation="vertical"        android:layout_height="match_parent">        <Button            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:onClick="listPop"            android:text="listPop"            />        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="Hello World!" />        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="Hello World!" />        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="Hello World!" />        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="Hello World!" />    </android.support.v7.widget.LinearLayoutCompat>**

好想LinearLayout也可以在4.0以上,具体没尝试;大家可以试试;直接用LinearLayout;不用着个v7兼容包的类。
————————————————-正式进入源码分析————————————
第一步我们打开v7包在android.support.v7.widget.LinearLayoutCompat中的源码(源码在哪,你能来看就不要问我了,对吧!!

然后,先看头部注释;这个很重用,一般这个注释都归纳了这个类的作用、用法等
A Layout that arranges its children in a single column or a single row. The direction of
the row can be set by calling {@link #setOrientation(int) setOrientation()}.
You can also specify gravity, which specifies the alignment of all the child elements by
calling {@link #setGravity(int) setGravity()} or specify that specific children
grow to fill up any remaining space in the layout by setting the weight member of
{@link LinearLayoutCompat.LayoutParams LinearLayoutCompat.LayoutParams}.
The default orientation is horizontal.
Also see {@link LinearLayoutCompat.LayoutParams} for layout attributes
这里主要讲的是这个类是一个布局,可以将其放置在一个单独列或一行中,可以设置方向,对齐方式等。。

我们在往下看:构造函数—实现3个函数,在最后一个构造函数中实现初始化;
在看看onDraw方法,这是这个类效果绘制的方法;

  @Override    protected void onDraw(Canvas canvas) {    //这里要设置mDivider要注意,不设置是是不会画后面的线的        if (mDivider == null) {            return;        }    //根据方向画线        if (mOrientation == VERTICAL) {            drawDividersVertical(canvas);        } else {            drawDividersHorizontal(canvas);        }    }    //画垂直线  void drawDividersVertical(Canvas canvas) {      //拿全部的子控件数        final int count = getVirtualChildCount();        for (int i = 0; i < count; i++) {        //具体的子控件            final View child = getVirtualChildAt(i);            if (child != null && child.getVisibility() != GONE) {                if (hasDividerBeforeChildAt(i)) {                    final LayoutParams lp = (LayoutParams) child.getLayoutParams();                    final int top = child.getTop() - lp.topMargin - mDividerHeight;                    drawHorizontalDivider(canvas, top);                }            }        }        if (hasDividerBeforeChildAt(count)) {            final View child = getLastNonGoneChild();            int bottom = 0;            if (child == null) {                bottom = getHeight() - getPaddingBottom() - mDividerHeight;            } else {                final LayoutParams lp = (LayoutParams) child.getLayoutParams();                bottom = child.getBottom() + lp.bottomMargin;            }            drawHorizontalDivider(canvas, bottom);        }    }    //调用Drawable这个工具类来画图  void drawHorizontalDivider(Canvas canvas, int top) {  //在看这个类的时候,我们要注意一些方法:Drawable类最前面的注释;基本上你就能大体掌握这个类,下次我专门搞个详解;        mDivider.setBounds(getPaddingLeft() + mDividerPadding, top,                getWidth() - getPaddingRight() - mDividerPadding, top + mDividerHeight);        mDivider.draw(canvas);    }    //画横线  void drawDividersHorizontal(Canvas canvas) {        final int count = getVirtualChildCount();        final boolean isLayoutRtl = ViewUtils.isLayoutRtl(this);        for (int i = 0; i < count; i++) {            final View child = getVirtualChildAt(i);            if (child != null && child.getVisibility() != GONE) {                //判断子控件位置                 if (hasDividerBeforeChildAt(i)) {                    final LayoutParams lp = (LayoutParams) child.getLayoutParams();                    final int position;                    if (isLayoutRtl) {                        position = child.getRight() + lp.rightMargin;                    } else {                        position = child.getLeft() - lp.leftMargin - mDividerWidth;                    }                    drawVerticalDivider(canvas, position);                }            }        }        if (hasDividerBeforeChildAt(count)) {            final View child = getVirtualChildAt(count - 1);            int position;            if (child == null) {                if (isLayoutRtl) {                    position = getPaddingLeft();                } else {                    position = getWidth() - getPaddingRight() - mDividerWidth;                }            } else {                final LayoutParams lp = (LayoutParams) child.getLayoutParams();                if (isLayoutRtl) {                    position = child.getLeft() - lp.leftMargin - mDividerWidth;                } else {                    position = child.getRight() + lp.rightMargin;                }            }            drawVerticalDivider(canvas, position);        }    }    //上面已经说了    void drawVerticalDivider(Canvas canvas, int left) {        mDivider.setBounds(left, getPaddingTop() + mDividerPadding,                left + mDividerWidth, getHeight() - getPaddingBottom() - mDividerPadding);        mDivider.draw(canvas);    } /**     * Determines where to position dividers between children.     *(判断子控件位置;也就是我们在xml中(begin|end|middle|none}))     * @param childIndex Index of child to check for preceding divider     * @return true if there should be a divider before the child at childIndex     * @hide Pending API consideration. Currently only used internally by the system.     */    protected boolean hasDividerBeforeChildAt(int childIndex) {        if (childIndex == 0) {            return (mShowDividers & SHOW_DIVIDER_BEGINNING) != 0;        } else if (childIndex == getChildCount()) {            return (mShowDividers & SHOW_DIVIDER_END) != 0;        } else if ((mShowDividers & SHOW_DIVIDER_MIDDLE) != 0) {            boolean hasVisibleViewBefore = false;            for (int i = childIndex - 1; i >= 0; i--) {                if (getChildAt(i).getVisibility() != GONE) {                    hasVisibleViewBefore = true;                    break;                }            }            return hasVisibleViewBefore;        }        return false;    }

好了,看了这么多的源码,你总改有所了解了吧

0 0
原创粉丝点击