Android XML靈活佈局之 EditText實現自適應高度同時限制最小和最大高度

Android中使用XML佈局應該是全部安卓開發者最熟悉的操做了,各類佈局的特性想必你們也都瞭如指掌。可是,真正利用好各個佈局以達到性能最優,或者配合實現一些單個佈局沒法實現的特性,在筆者看來是一個很是值得花心思去研究的問題。本文提供的解題思路並不複雜,若是你有其餘方案(只經過xml實現),歡迎在評論中留言。android

效果展現

很少廢話,直接一個圖看下要達到的效果⬇️api

Jun-06-2019 19-34-17

在這個佈局中,EditText實現了高度自適配,但限制於一屏內,文字超過一屏時則在EditText控件內進行滑動。充分利用了EditText的特性,避免了ScrollView的使用。app

實現思路

爲了實現圖中的效果,分析可知最關鍵的點有三個:佈局

  • 有最低高度。這個最簡單,用EditText自帶的minLines就能夠達成效果性能

  • 高度要設爲 android:layout_height="wrap_content"測試

  • EditText所佔的空間只有一屏內的空白區域,而且不能超出此區域ui

因而我開始了不斷嘗試:spa

簡單的LinearLayoutFrameLayout都會出現當文字超出一屏高度時,直接就往屏幕外部繼續延長了。由於沒辦法將其限制在某個區域裏,若是用LinearLayout的權重效果,那等因而直接佔滿空白區域了,明顯也不是咱們想要的。3d

那麼須要一個能夠限制其所在範圍的佈局,是否是一下就想到了用的最多也最方便的ConstrainLayout。惋惜ConstrainLayout也不行,哪怕限制了底邊相關聯,但若是不設置高度爲0dp,wrap_content的狀況仍然會超出屏幕,而高度設爲0時等於直接佔滿了。code

一樣還有使用Chains鏈,不只位置沒法固定,並且也解決不了高度越出的問題。最後我甚至還嘗試了使用兩個EditText,同時輸入一樣的文字,一個隱藏掉只用來肯定高度,另外一個按它的高度進行適配。結果固然也失敗了,至少只用ConstrainLayout我是沒有達成效果。

解決方案

在屢次失敗後,我一度覺得是否是沒法實現這樣的效果了,要麼妥協將EditText設爲固定高度,或者使用ScrollView來配合,或者經過代碼動態獲取文字高度來設置控件高度。

但總不能那麼輕易妥協,而後我想起了RelativeLayout,這個自從有了ConstrainLayout以後就已經被冷落了的佈局。原本我覺得後者是前者的"plus版",大哥都作不到的,小弟怎麼能作到呢?

結果我還真被打臉了,測試後發現,EditTextRelativeLayout佈局內,高度設爲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="@dimen/dp_42" app:leftText="返回" app:leftTextDrawableLeft="@mipmap/top_return" />

    <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="@dimen/dp_42">

        <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="@dimen/dp_62" 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="@dimen/dp_14" 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>
複製代碼

最後

一番實驗下來我發現雖然ConstrainLayoutRelativeLayout的不少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不太靈活的一點,雖然須要設負值的狀況不多見。

以上就是我在項目中本身發現的比較有意思的地方,雖然簡單,但若是能幫助到別人就挺好的啦。

相關文章
相關標籤/搜索