Android XML灵活布局之 EditText实现自适应高度同时限制最小和最大高度

栏目: 编程语言 · XML · 发布时间: 6年前

内容简介:本文已发到我的小号:Android中使用XML布局应该是所有安卓开发者最熟悉的操作了,各种布局的特性想必大家也都了如指掌。但是,真正利用好各个布局以达到性能最优,或者配合实现一些单个布局无法实现的特性,在笔者看来是一个非常值得花心思去研究的问题。本文提供的解题思路并不复杂,如果你有其他方案(只通过xml实现),欢迎在评论中留言。不多废话,直接一个图看下要达到的效果:arrow_down:

本文已发到我的小号: juejin.im/post/5d033d…

Android中使用XML布局应该是所有安卓开发者最熟悉的操作了,各种布局的特性想必大家也都了如指掌。但是,真正利用好各个布局以达到性能最优,或者配合实现一些单个布局无法实现的特性,在笔者看来是一个非常值得花心思去研究的问题。本文提供的解题思路并不复杂,如果你有其他方案(只通过xml实现),欢迎在评论中留言。

效果展示

不多废话,直接一个图看下要达到的效果:arrow_down:

Android XML灵活布局之 EditText实现自适应高度同时限制最小和最大高度

在这个布局中, EditText 实现了高度自适配,但限制于一屏内,文字超过一屏时则在 EditText 控件内进行滑动。充分利用了 EditText 的特性,避免了 ScrollView 的使用。

实现思路

为了实现图中的效果,分析可知最关键的点有三个:

  • 有最低高度。这个最简单,用 EditText 自带的 minLines 就可以达成效果

  • 高度要设为 android:layout_height="wrap_content"

  • EditText所占的空间只有一屏内的空白区域,并且不能超出此区域

于是我开始了不断尝试:

简单的 LinearLayoutFrameLayout 都会出现当文字超出一屏高度时,直接就往屏幕外部继续延长了。因为没办法将其限制在某个区域里,如果用 LinearLayout 的权重效果,那等于是直接占满空白区域了,明显也不是我们想要的。

那么需要一个可以限制其所在范围的布局,是不是一下就想到了用的最多也最方便的 ConstrainLayout 。可惜 ConstrainLayout 也不行,哪怕限制了底边相关联,但如果不设置高度为0dp, wrap_content 的情况仍然会超出屏幕,而高度设为0时等于直接占满了。

同样还有使用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 不太灵活的一点,虽然需要设负值的情况很少见。

以上就是我在项目中自己发现的比较有意思的地方,虽然简单,但如果能帮助到别人就挺好的啦。


以上所述就是小编给大家介绍的《Android XML灵活布局之 EditText实现自适应高度同时限制最小和最大高度》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Data Structures and Algorithm Analysis in Java

Data Structures and Algorithm Analysis in Java

Mark A. Weiss / Pearson / 2011-11-18 / GBP 129.99

Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course wa......一起来看看 《Data Structures and Algorithm Analysis in Java》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换