Space源码分析

yo3qbq3ctu 8年前
   <h2>简介</h2>    <pre>  <code class="language-java">public final class Space extends View</code></pre>    <p>Space是一个轻量的View,可以在布局中被用来创建间隙,常用于布局优化。</p>    <p>介于可能很多人根本不知道Space的存在!所以稍微提一下它的使用场景,比如以下场景的右侧小三角,就可以使用Space:</p>    <p><img src="https://simg.open-open.com/show/4d4a100ed31f8380ff1b2473baf81936.jpg"></p>    <p>在两个三角之间放置一个 Space ,两三角分别位于它的上下,控制它的高度就能控制三角之间的间隔。</p>    <pre>  <code class="language-java"><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>    <h2>构造方法分析</h2>    <p>看第一个构造方法即可。</p>    <pre>  <code class="language-java">// 最终都会调用这个构造方法  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>    <p>/**</p>    <ul>     <li>Draw nothing.<br> *</li>     <li>@param canvas an unused parameter.<br> */<br> @Override<br> public void draw(Canvas canvas) {<br> //空方法<br> }</li>    </ul>    <p>/**</p>    <ul>     <li>Compare to: {@link View#getDefaultSize(int, int)}</li>     <li>If mode is AT_MOST, return the child size instead of the parent size</li>     <li> <p>(unless it is too big).</p> <p>*/</p> <p>private static int getDefaultSize2(int size, int measureSpec) {</p> <p>int result = size;</p> <p>int specMode = MeasureSpec.getMode(measureSpec);</p> <p>int specSize = MeasureSpec.getSize(measureSpec);</p> <p>switch (specMode) {</p> <pre>  <code class="language-java">case MeasureSpec.UNSPECIFIED:      result = size;      break;  case MeasureSpec.AT_MOST: //wrap_content 返回更小的值      result = Math.min(size, specSize);      break;  case MeasureSpec.EXACTLY:      result = specSize;      break;</code></pre> <p>}</p> <p>return result;</p> <p>}</p> </li>    </ul>    <p>@Override</p>    <p>protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {</p>    <p>// getSuggestedMinimumWidth() 根据minWidth以及背景的宽度来返回</p>    <p>setMeasuredDimension(</p>    <p>getDefaultSize2(getSuggestedMinimumWidth(), widthMeasureSpec),</p>    <p>getDefaultSize2(getSuggestedMinimumHeight(), heightMeasureSpec));</p>    <p>}</p>    <p>```</p>    <p>Space跟ViewStub一个套路, draw() 都为空方法,然后重写 onMeasure ,相比ViewStub,Space代码更加比较简单。</p>    <p>另外一般我们使用Space都是会指定宽高,大部分走的是 EXACTLY的流程。</p>    <h2>要点</h2>    <ol>     <li>Space 用来做间隙非常有用</li>     <li>Space 默认为不可见(invisible),但是有宽高,会占据空间。</li>     <li>布局文件中设置 VISIBLE 无效。</li>    </ol>    <h2>小结</h2>    <p>ViewStub跟Space作为Android布局优化的常用手段,有着一些同样的思路值得我们去学习:</p>    <ul>     <li>不绘制(减少overDraw)</li>     <li>优化或者不参与测量与布局(提高整体布局的渲染速度)</li>    </ul>    <p> </p>    <p>来自:http://yifeiyuan.me/2016/12/29/analyze-space/</p>    <p> </p>