LinearLayout開頭、結尾分割線顯示錯誤

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>

圖片1
佈局很簡單,分割線在最後顯示。

然而當我們設置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了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章