You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用Google Material库,如何为EditText实现底部边框高亮效果?

嘿,我来帮你搞定这个底部边框高亮的需求!不用依赖官方Material Design库,也不一定非得写自定义View,有几种实用方案都能实现你要的效果,而且全部支持API 19及以上~

方案一:原生Drawable组合(最简单高效)

这个方案完全用Android原生的Drawable实现,不用写Java/Kotlin代码,直接通过XML配置就能搞定。核心思路是用layer-list和selector来切换聚焦/非聚焦状态的样式。

步骤1:创建默认状态的底部边框Drawable

在res/drawable下新建edittext_bottom_border.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 透明背景,避免覆盖EditText的默认交互效果 -->
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
    <!-- 底部灰色边框,上下左右只保留底部 -->
    <item android:top="-2dp" android:left="-2dp" android:right="-2dp">
        <shape android:shape="rectangle">
            <stroke android:width="2dp" android:color="#CCCCCC" />
        </shape>
    </item>
    <!-- 默认隐藏的高亮条 -->
    <item android:gravity="bottom">
        <shape android:shape="rectangle">
            <solid android:color="#2196F3" /> <!-- Material蓝,可自行替换 -->
            <size android:height="2dp" />
        </shape>
    </item>
</layer-list>

步骤2:创建聚焦状态的Drawable

新建res/drawable/edittext_bottom_border_selected.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
    <!-- 聚焦时边框变高亮色 -->
    <item android:top="-2dp" android:left="-2dp" android:right="-2dp">
        <shape android:shape="rectangle">
            <stroke android:width="2dp" android:color="#2196F3" />
        </shape>
    </item>
    <!-- 聚焦时显示高亮条 -->
    <item android:gravity="bottom">
        <shape android:shape="rectangle">
            <solid android:color="#2196F3" />
            <size android:height="2dp" />
        </shape>
    </item>
</layer-list>

步骤3:创建状态选择器

新建res/drawable/edittext_border_selector.xml,用来根据焦点状态切换样式:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/edittext_bottom_border_selected" android:state_focused="true" />
    <item android:drawable="@drawable/edittext_bottom_border" />
</selector>

步骤4:在布局中使用

把这个选择器设为EditText的背景即可:

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/edittext_border_selector"
    android:padding="16dp"
    android:textColor="@android:color/black" />

这个方案零代码,完全原生,API 19完美兼容,是最推荐的方案。

方案二:自定义View(灵活扩展)

如果你需要更个性化的效果(比如高亮条从中间展开的动画、动态修改颜色等),可以自定义一个EditText,通过重写onDraw来绘制边框和高亮条。

自定义View代码(Java)

public class CustomBorderEditText extends androidx.appcompat.widget.AppCompatEditText {
    private Paint borderPaint;
    private Paint highlightPaint;
    // 默认样式参数
    private int borderColor = Color.parseColor("#CCCCCC");
    private int highlightColor = Color.parseColor("#2196F3");
    private int borderWidth = 2;
    private int highlightHeight = 2;
    private boolean isFocused = false;

    public CustomBorderEditText(Context context) {
        super(context);
        init();
    }

    public CustomBorderEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
        // 支持通过XML自定义属性
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomBorderEditText);
        borderColor = ta.getColor(R.styleable.CustomBorderEditText_borderColor, borderColor);
        highlightColor = ta.getColor(R.styleable.CustomBorderEditText_highlightColor, highlightColor);
        borderWidth = ta.getDimensionPixelSize(R.styleable.CustomBorderEditText_borderWidth, borderWidth);
        highlightHeight = ta.getDimensionPixelSize(R.styleable.CustomBorderEditText_highlightHeight, highlightHeight);
        ta.recycle();
    }

    private void init() {
        // 初始化画笔
        borderPaint = new Paint();
        borderPaint.setColor(borderColor);
        borderPaint.setStrokeWidth(borderWidth);
        borderPaint.setStyle(Paint.Style.STROKE);

        highlightPaint = new Paint();
        highlightPaint.setColor(highlightColor);
        highlightPaint.setStyle(Paint.Style.FILL);

        // 去掉默认背景,避免冲突
        setBackground(null);
        setPadding(16, 16, 16, 16);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 绘制底部边框
        canvas.drawLine(0, getHeight() - borderWidth, getWidth(), getHeight() - borderWidth, borderPaint);
        // 聚焦时绘制高亮条
        if (isFocused) {
            canvas.drawRect(0, getHeight() - highlightHeight, getWidth(), getHeight(), highlightPaint);
        }
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        isFocused = focused;
        invalidate(); // 焦点变化时重绘视图
    }
}

添加自定义属性

在res/values/attrs.xml中添加自定义属性,方便在XML中配置样式:

<declare-styleable name="CustomBorderEditText">
    <attr name="borderColor" format="color" />
    <attr name="highlightColor" format="color" />
    <attr name="borderWidth" format="dimension" />
    <attr name="highlightHeight" format="dimension" />
</declare-styleable>

布局中使用

<com.yourpackage.CustomBorderEditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:borderColor="#CCCCCC"
    app:highlightColor="#2196F3"
    app:borderWidth="2dp"
    app:highlightHeight="2dp" />

这个方案可以轻松扩展动画效果(比如用ValueAnimator实现高亮条的展开动画),完全控制绘制逻辑,API 19也能完美支持。

方案三:轻量第三方库(可选)

如果你不想自己写代码,又无法使用官方Material库,可以考虑一些轻量的第三方Material风格控件库,比如com.github.florent37:materialtextfield:1.0.7,这个库体积小,支持API 16+,提供了类似Material Design的输入框样式。不过这个方案需要依赖第三方库,如果你有不能引入第三方库的限制,还是优先前两种方案。


内容的提问来源于stack exchange,提问作者Artem Griukov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:02:22