LinearLayout
在佈局文件設置分割線不僅方便,而且高效,對於佈局來說十分重要。然而我在爲LinearLayout
設置分割線的時候卻碰到一個問題,十分不解。先來看看是什麼現象吧:
佈局文件如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:divider="@drawable/divider"
android:showDividers="end"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
android:textSize="50sp"
android:visibility="visible"
android:id="@+id/textView" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editText"
android:text="EditText"
android:textSize="50sp"
android:background="@null"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="@+id/button"
android:visibility="visible"
/>
</LinearLayout>
佈局很簡單,分割線在最後顯示。
然而當我們設置Button
屬性android:visibility="gone"
後,再來看看:
分割線竟然跑最上面了!
然後還是最開始的佈局,我們設置LinearLayout
屬性android:showDividers="beginning"
,顯示效果爲:
然後設置TextView
屬性android:visibility="gone"
後,再來看看:
分割線消失了!
到網上搜了搜沒有找到相關的問題,沒辦法,看源碼吧。
下面是LinearLayout
畫水平分割線的函數:
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 = getVirtualChildAt(count - 1);
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);
}
}
for
循環中,i=0是第一個view,也就是上面佈局中的TextView
,設置不可見時,drawHorizontalDivider(canvas, top)
不被執行,也就是開頭的分割線沒有畫出來的原因。下面代碼:
if (hasDividerBeforeChildAt(count)) { final View child = getVirtualChildAt(count - 1); 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); }
這段代碼是用來畫結尾的分割線的,當我們設置
Button
屬性android:visibility="gone"
時,child.getBottom()
爲0,所以分割線就畫到離頂端lp.bottomMargin
的位置了。
原因雖然找到了,但還是沒有什麼好的解決方案,只能靠我們自己設置表示分割線的View了。