如果editText位于TextInputlayout内,则将drawableLeft添加到EditText会将提示向右移动 [英] Adding a drawableLeft to an EditText shifts the hint towards right, if edittext is inside TextInputlayout

查看:123
本文介绍了如果editText位于TextInputlayout内,则将drawableLeft添加到EditText会将提示向右移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在TextInputLayout中创建了一个EditText.我在运行时在代码中将drawableLeft设置为EditText,但是一旦我添加了drawableLeft,TextInputLayout中的浮动提示就会向右移动,从而使空间等于可绘制的宽度.但是我不想在提示中留出空间,所以请帮助我解决这个问题!

I have make an EditText inside TextInputLayout. I am setting a drawableLeft to an EditText at runtime in my code, but as soon as I add the drawableLeft the floating hint inside TextInputLayout shifts to right leaving the space equal to drawable width. But I dont want that space in hint, so help me to resolve this!!

推荐答案

TextInputLayout使用助手类-CollapsingTextHelper-来操纵其提示文本.该帮助程序的实例是私有的,并且与它的布局关联的所有属性都没有公开,因此我们需要使用一些反射来访问它.此外,每次布置TextInputLayout时,都会设置并重新计算其属性,因此有必要将TextInputLayout子类化,覆盖其onLayout()方法,然后在此处进行调整.

TextInputLayout uses a helper class - CollapsingTextHelper - to manipulate its hint text. The instance of this helper is private, and none of the attributes associated with its layout are exposed, so we'll need to use a little reflection to get access to it. Furthermore, its properties are set and recalculated every time the TextInputLayout is laid out, so it makes sense to subclass TextInputLayout, override its onLayout() method, and make our adjustments there.

import android.content.Context;
import android.graphics.Rect;
import android.support.design.widget.TextInputLayout;
import android.util.AttributeSet;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class CustomTextInputLayout extends TextInputLayout {
    private Object collapsingTextHelper;
    private Rect bounds;
    private Method recalculateMethod;

    public CustomTextInputLayout(Context context) {
        this(context, null);
    }

    public CustomTextInputLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        adjustBounds();
    }

    private void init() {
        try {
            Field cthField = TextInputLayout.class.getDeclaredField("mCollapsingTextHelper");
            cthField.setAccessible(true);
            collapsingTextHelper = cthField.get(this);

            Field boundsField = collapsingTextHelper.getClass().getDeclaredField("mCollapsedBounds");
            boundsField.setAccessible(true);
            bounds = (Rect) boundsField.get(collapsingTextHelper);

            recalculateMethod = collapsingTextHelper.getClass().getDeclaredMethod("recalculate");
        }
        catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException e) {
            collapsingTextHelper = null;
            bounds = null;
            recalculateMethod = null;
            e.printStackTrace();
        }
    }

    private void adjustBounds() {
        if (collapsingTextHelper == null) {
            return;
        }

        try {
            bounds.left = getEditText().getLeft() + getEditText().getPaddingLeft();
            recalculateMethod.invoke(collapsingTextHelper);
        }
        catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
            e.printStackTrace();
        }
    }
}

此自定义类是常规TextInputLayout的直接替代,您将以相同的方式使用它.例如:

This custom class is a drop-in replacement for the regular TextInputLayout, and you would use it the same way. For example:

<com.mycompany.myapp.CustomTextInputLayout
    android:id="@+id/text_input_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Model (Example i10, Swift, etc.)"
    app:hintTextAppearance="@style/TextLabel">

    <android.support.design.widget.TextInputEditText
        android:id="@+id/edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:drawableLeft="@drawable/bmw"
        android:text="M Series" />

</com.mycompany.myapp.CustomTextInputLayout>



注意:

  • 在移至材料组件"库中时,帮助程序类的字段名称和范围已删除了m前缀表示法.如评论中所述,它们现在分别命名为collapsingTextHelpercollapsedBounds.

  • In the move to the Material Components library, the field names for the helper class and the bounds have dropped the m prefix notation. As noted in comments, they are now named collapsingTextHelper and collapsedBounds, respectively.

从API级别28(Pie)开始,某些

As of API level 28 (Pie), there are certain Restrictions on non-SDK interfaces, including reflection, to access normally inaccessible members in the SDK. However, the various available documents seem to indicate that reflection on components within your own package are not prohibited. As the support library is not part of the platform SDK, and is merged into your package when built, this solution should still be valid. Indeed, recent testing has uncovered no issues, and this still works as expected on the available Pie emulators.

这篇关于如果editText位于TextInputlayout内,则将drawableLeft添加到EditText会将提示向右移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆