本文已發到個人小號:juejin.im/post/5d033d…android
Android中使用XML佈局應該是全部安卓開發者最熟悉的操做了,各類佈局的特性想必你們也都瞭如指掌。可是,真正利用好各個佈局以達到性能最優,或者配合實現一些單個佈局沒法實現的特性,在筆者看來是一個很是值得花心思去研究的問題。本文提供的解題思路並不複雜,若是你有其餘方案(只經過xml實現),歡迎在評論中留言。api
很少廢話,直接一個圖看下要達到的效果⬇️app
在這個佈局中,EditText
實現了高度自適配,但限制於一屏內,文字超過一屏時則在EditText
控件內進行滑動。充分利用了EditText
的特性,避免了ScrollView
的使用。佈局
爲了實現圖中的效果,分析可知最關鍵的點有三個:post
有最低高度。這個最簡單,用EditText
自帶的minLines
就能夠達成效果性能
高度要設爲 android:layout_height="wrap_content"
測試
EditText所佔的空間只有一屏內的空白區域,而且不能超出此區域ui
因而我開始了不斷嘗試:spa
簡單的LinearLayout
和FrameLayout
都會出現當文字超出一屏高度時,直接就往屏幕外部繼續延長了。由於沒辦法將其限制在某個區域裏,若是用LinearLayout
的權重效果,那等因而直接佔滿空白區域了,明顯也不是咱們想要的。3d
那麼須要一個能夠限制其所在範圍的佈局,是否是一下就想到了用的最多也最方便的ConstrainLayout
。惋惜ConstrainLayout
也不行,哪怕限制了底邊相關聯,但若是不設置高度爲0dp,wrap_content
的狀況仍然會超出屏幕,而高度設爲0時等於直接佔滿了。
一樣還有使用Chains鏈,不只位置沒法固定,並且也解決不了高度越出的問題。最後我甚至還嘗試了使用兩個EditText
,同時輸入一樣的文字,一個隱藏掉只用來肯定高度,另外一個按它的高度進行適配。結果固然也失敗了,至少只用ConstrainLayout
我是沒有達成效果。
在屢次失敗後,我一度覺得是否是沒法實現這樣的效果了,要麼妥協將EditText
設爲固定高度,或者使用ScrollView
來配合,或者經過代碼動態獲取文字高度來設置控件高度。
但總不能那麼輕易妥協,而後我想起了RelativeLayout
,這個自從有了ConstrainLayout
以後就已經被冷落了的佈局。原本我覺得後者是前者的"plus版",大哥都作不到的,小弟怎麼能作到呢?
結果我還真被打臉了,測試後發現,EditText
在RelativeLayout
佈局內,高度設爲wrap_content
時,既能夠自適應高度,並且控件高度會被直接限制在根佈局RelativeLayout
內,也就是不會越出屏幕!
這下就真的能實現了,下面直接貼上代碼:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white_fff" android:fitsSystemWindows="true" android:focusable="true" android:focusableInTouchMode="true">
<com.widget.TitleBar android:id="@+id/titlebar" android:layout_width="match_parent" android:layout_height="42dp" app:leftText="返回" app:leftTextDrawableLeft="@mipmap/top_return" />
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="42dp">
<EditText android:id="@+id/et_notice" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="24dp" android:layout_marginTop="14dp" android:layout_marginEnd="24dp" android:layout_marginBottom="62dp" android:background="@drawable/guild_rect_solid_f2f2f2_radius_3" android:gravity="start" android:hint="請輸入公會公告" android:includeFontPadding="false" android:lineSpacingMultiplier="1.2" android:maxLength="1000" android:minLines="8" android:paddingStart="14dp" android:paddingTop="12dp" android:paddingEnd="14dp" android:paddingBottom="12dp" android:textAppearance="@style/guild_TextAppearance.262122_14"/>
<TextView android:id="@+id/tv_word_count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignStart="@+id/et_notice" android:layout_alignTop="@+id/tv_push" android:layout_alignBottom="@+id/tv_push" android:gravity="center" android:includeFontPadding="false" android:text="@string/guild_notice_tip" android:textColor="@color/grey_999" android:textSize="11sp" />
<TextView android:id="@+id/tv_push" android:layout_width="wrap_content" android:layout_height="22dp" android:layout_alignEnd="@+id/et_notice" android:layout_alignBottom="@+id/et_notice" android:layout_marginTop="14dp" android:layout_marginBottom="-36dp" android:background="@drawable/guild_rect_solid_f81a1a_radius_11" android:gravity="center" android:includeFontPadding="false" android:paddingStart="9dp" android:paddingEnd="9dp" android:text="發佈" android:textColor="@color/white_fff" android:textSize="12sp" />
</RelativeLayout>
</FrameLayout>
複製代碼
一番實驗下來我發現雖然ConstrainLayout
和RelativeLayout
的不少api效果是差很少的,但實際上確實在一些臨界狀況上仍是有不同的表現。
好比RelativeLayout的layout_alignBottom="@+id/et_notice"
、layout_alignParentBottom="true"
的效果就是"底部對齊於其餘控件的底部"和"底部對齊於根佈局View的底部"。在ConstrainLayout
中對應layout_constraintBottom_toBottomOf="@+id/et_notice"
和layout_constraintBottom_toBottomOf="parent"
。
雖然好像效果同樣,不過ConstrainLayout
中的margin
是沒法設置負值的,而其餘佈局能夠,這一點是我以爲是ConstrainLayout
不太靈活的一點,雖然須要設負值的狀況不多見。
以上就是我在項目中本身發現的比較有意思的地方,雖然簡單,但若是能幫助到別人就挺好的啦。