Space源碼分析

簡介

public final class Space extends View

Space是一個輕量的View,可以在布局中被用來創建間隙,常用于布局優化。

介于可能很多人根本不知道Space的存在!所以稍微提一下它的使用場景,比如以下場景的右側小三角,就可以使用Space:

在兩個三角之間放置一個 Space ,兩三角分別位于它的上下,控制它的高度就能控制三角之間的間隔。

<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_alignParentRight="true"
    android:layout_marginRight="2dp"
    >

<ImageView
    android:id="@+id/iv_price_up"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_above="@+id/divider"
    android:background="@drawable/price_up"
    android:layout_marginBottom="1dp"
    />

<Space
    android:layout_width="wrap_content"
    android:layout_height="1dp"
    android:id="@+id/divider"
    android:layout_centerInParent="true"
    />

<ImageView
    android:id="@+id/iv_price_down"
    android:layout_marginTop="1dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/divider"
    android:background="@drawable/price_down"
    />

</RelativeLayout> </code></pre>

構造方法分析

看第一個構造方法即可。

// 最終都會調用這個構造方法
publicSpace(Context context, AttributeSet attrs,intdefStyleAttr,intdefStyleRes){
    super(context, attrs, defStyleAttr, defStyleRes);
    // 如果是VISIBLE 則改為 INVISIBLE
    if (getVisibility() == VISIBLE) {
        setVisibility(INVISIBLE);
    }
}

publicSpace(Context context, AttributeSet attrs,intdefStyleAttr){ this(context, attrs, defStyleAttr, 0); }

publicSpace(Context context, AttributeSet attrs){ this(context, attrs, 0); }

publicSpace(Context context){ //noinspection NullableProblems this(context, null); } ```

跟ViewStub類似,Space在構造方法里做了一些操作:當可見性為VISIBLE的時候,把它改為INVISIBLE了

由于Space方法非常少,接下去直接都分析了。

其余方法分析

</code></pre>

/**

  • Draw nothing.
    *
  • @param canvas an unused parameter.
    */
    @Override
    public void draw(Canvas canvas) {
    //空方法
    }

/**

  • Compare to: {@link View#getDefaultSize(int, int)}
  • If mode is AT_MOST, return the child size instead of the parent size
  • (unless it is too big).

    */

    private static int getDefaultSize2(int size, int measureSpec) {

    int result = size;

    int specMode = MeasureSpec.getMode(measureSpec);

    int specSize = MeasureSpec.getSize(measureSpec);

    switch (specMode) {

    case MeasureSpec.UNSPECIFIED:
        result = size;
        break;
    case MeasureSpec.AT_MOST: //wrap_content 返回更小的值
        result = Math.min(size, specSize);
        break;
    case MeasureSpec.EXACTLY:
        result = specSize;
        break;

    }

    return result;

    }

<p>@Override</p>

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// getSuggestedMinimumWidth() 根據minWidth以及背景的寬度來返回

setMeasuredDimension(

getDefaultSize2(getSuggestedMinimumWidth(), widthMeasureSpec),

getDefaultSize2(getSuggestedMinimumHeight(), heightMeasureSpec));

}

```

Space跟ViewStub一個套路, draw() 都為空方法,然后重寫 onMeasure ,相比ViewStub,Space代碼更加比較簡單。

另外一般我們使用Space都是會指定寬高,大部分走的是 EXACTLY的流程。

要點

  1. Space 用來做間隙非常有用
  2. Space 默認為不可見(invisible),但是有寬高,會占據空間。
  3. 布局文件中設置 VISIBLE 無效。

小結

ViewStub跟Space作為Android布局優化的常用手段,有著一些同樣的思路值得我們去學習:

  • 不繪制(減少overDraw)
  • 優化或者不參與測量與布局(提高整體布局的渲染速度)

 

來自:http://yifeiyuan.me/2016/12/29/analyze-space/

 

 本文由用戶 yo3qbq3ctu 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!