23

我想知道是否可以始终保持标签展开,无论EditText. 我在源代码中四处查看,它是使用 aValueAnimator和 a counterinside aTextWatcher来动画或不动画变化。也许我可以在里面设置一个自定义TextWatcher的自定义?ValueAnimatorEditTextTextInputLayout

4

5 回答 5

10

当前版本的TextInputLayout存在专门做一件事 - 根据是否有一些文本显示/隐藏帮助标签EditText。你想要的是不同的行为,所以你需要一个不同于TextInputLayout. 这个案例是编写适合您需求的自定义视图的完美候选者。

也就是说,您将自定义设置为的想法TextWatcherEditText行不通,因为TextInputLayout它没有暴露任何实际处理动画的内部结构 - 也没有updateLabelVisibility(), setEditText(),做这项工作的魔法Handler或其他任何东西。当然,我们当然不想为这样的细节走反射路径,所以......

只需使用MaterialEditText!它具有以下属性,可以完全满足您的要求。

met_floatingLabelAlwaysShown : 总是显示浮动标签,而不是动画它进/出。默认为假。

该库非常稳定(我自己在两个不同的项目中使用它)并且有很多自定义选项。希望能帮助到你!

于 2016-02-22T22:19:59.640 回答
8

尽管有最佳答案,但我仍然简单地提出了一个 Java 反射解决方案来实现所需的行为(使用com.google.android.material.textfield.TextInputLayoutfrom com.google.android.material:material:1.0.0):

/**
 * Creation Date: 3/20/19
 *
 * @author www.flx-apps.com
 */
public class CollapsedHintTextInputLayout extends TextInputLayout {
    Method collapseHintMethod;

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

    public CollapsedHintTextInputLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CollapsedHintTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    void init() {
        setHintAnimationEnabled(false);

        try {
            collapseHintMethod = TextInputLayout.class.getDeclaredMethod("collapseHint", boolean.class);
            collapseHintMethod.setAccessible(true);
        }
        catch (Exception ignored) {
            ignored.printStackTrace();
        }
    }

    @Override
    public void invalidate() {
        super.invalidate();
        try {
            collapseHintMethod.invoke(this, false);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Java 反射当然从来都不是漂亮的,但就我而言,它只是比创建类似外观的小部件更方便的解决方案,而且链接库似乎已经过时并且被遗弃了......:/

如果您使用它,请不要忘记添加相应的 ProGuard 规则:

-keepclassmembers class com.google.android.material.textfield.TextInputLayout {
    private void collapseHint;
}
于 2019-03-20T22:11:39.763 回答
8

对于支持设计 23.3.0 的我来说,它可以使用

              <android.support.design.widget.TextInputLayout
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:hint="wow such hint"
              app:hintEnabled="true"
              app:hintAnimationEnabled="false"
              />
于 2016-07-01T10:26:56.823 回答
2

新属性app:expandedHintEnabled(从 1.3.0 开始)解决了这个问题,无需子类化和其他 hack。

https://github.com/material-components/material-components-android/issues/810

于 2021-06-10T10:01:45.313 回答
1

这是您可以使用的一个技巧,它将允许您将标签提示放在布局中,并将文本框提示放在编辑文本中,而不会发生冲突。它也将比上述反射解决方案更好地工作,因为它可以防止发生原始不良绘图并且不需要您解决缩小/proguar 设置,因为它可以进行类与类之间的比较。

子类 TextInputEditText 如下:


import android.content.Context
import android.text.Editable
import android.text.SpannableStringBuilder
import android.util.AttributeSet
import com.google.android.material.R
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout

class MonkeyedTextInputEditText @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = R.attr.editTextStyle) : TextInputEditText(context, attrs, defStyleAttr) {
    @Override
    override fun getText(): Editable? {
        val text = super.getText()
        if (!text.isNullOrEmpty())
            return text
        /* We want this expression in TextInputLayout.java to be true if there's a hint set:
         *        final boolean hasText = editText != null && !TextUtils.isEmpty(editText.getText());
         * But for everyone else it should return the real value, so we check the caller.
         */
        if (!hint.isNullOrEmpty() && Thread.currentThread().stackTrace[3].className == TextInputLayout::class.qualifiedName)
            return SpannableStringBuilder(hint)
        return text
    }
}

然后您的布局可能如下所示:


<com.google.android.material.textfield.TextInputLayout
    ...
    android:hint="YOUR LABEL TEXT"
    ...
    >

    <yourapp.MonkeyedTextInputEditText
        ...
        android:hint="YOUR PLACEHOLDER TEXT"
        ...
        />
</com.google.android.material.textfield.TextInputLayout>
于 2020-03-31T21:52:38.103 回答