listView item 增加間距 以及item根部局 margin 失效原因

最近根據設計圖寫listView 的時候,listView個item 之間存在間距,左右上下都有,一開始的想法是在item 的根佈局 設置margin 屬性,但是在listView 中margin 無法生效,所以在此研究下失效的原因。而解決辦法就是在加一層佈局,作爲根佈局 設置padding ,或者 新增根佈局的下一次佈局設置margin.

下面直接看效果圖:
這裏寫圖片描述


1.解決辦法,我這裏使用的是再嵌套一層佈局加padding的方案

這裏寫圖片描述

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="horizontal"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:paddingTop="5dp"
              android:paddingBottom="5dp"
              android:paddingLeft="8dp"
              android:paddingRight="8dp"
              android:background="@color/transparent">

    <!-- 最上層控制item 的間隔的 -->
    <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="8dp"
            android:background="@drawable/home_listitem_style">

當然你也可以選擇 在再嵌套一層佈局的下面的一層佈局,使用margin 一樣的效果,如果沒有左右的間距只有上下的間距,還有一種方案就是 設置dividerHeight 的高度,顏色爲透明就可。

2.着重研究的是margin失效的原因

這是我看到的一段解釋,
The fact is that, the margin of LinearLayout (child) asks its parent layout (container) to give child layout a margin of x value.

So if the parent layouts’ LayoutParams support the margins then that margin is honored and applied.

ListView uses AbsListView.LayoutParams by default, which doesn’t include any margin support, just the height and width, thats why, it simply ignores the params value for margins.

  • 2.1 ListView extends AbsListView 查看 AbsListView 如何加入佈局參數的

這裏寫圖片描述

直接使用的是ViewGroup的 layoutParams, 沒有包含 margin 的信息,在viewGroup 源碼中發現

這裏寫圖片描述

有個叫 MarginLayoutParams 的類,繼續查看他的實現類 ,其中並沒有發現AbsListView,

這裏寫圖片描述

而在 ViewGroup layoutParams 中的實現類中卻發現了 AbsListView
這裏寫圖片描述

由此說明 listView 根佈局中 設置margin 直接被忽略了,因爲沒有實現 marginLayoutParams ,雖然子類LinearLayout 裏面設置margin 是有效的,但是其父類 AbsListView layoutparams 並沒有實現 marginLayoutParams,沒有提供相關的margin 的值,所以子類中也獲取不到對應的值,儘管已經設置了。

參考的資料:
http://stackoverflow.com/questions/16278159/why-linearlayouts-margin-is-being-ignored-if-used-as-listview-row-view

3.爲什麼margin 失效,padding 卻有效呢?

我個人的理解是:padding 是內邊距,不需要父類,自己就是父類,就可以提供子類具體的距離和值等,而margin 是外邊距,需要父類提供具體的距離,當父類不支持就無法獲取到對應的值。

LinearLayout extends ViewGroup extends View

view 本身就可以提供padding 的屬性,而margin 卻需要父類的支持。

這裏寫圖片描述

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