我想知道是否可以始终保持标签展开,无论EditText
. 我在源代码中四处查看,它是使用 aValueAnimator
和 a counter
inside aTextWatcher
来动画或不动画变化。也许我可以在里面设置一个自定义TextWatcher
的自定义?ValueAnimator
EditText
TextInputLayout
5 回答
当前版本的TextInputLayout
存在专门做一件事 - 根据是否有一些文本显示/隐藏帮助标签EditText
。你想要的是不同的行为,所以你需要一个不同于TextInputLayout
. 这个案例是编写适合您需求的自定义视图的完美候选者。
也就是说,您将自定义设置为的想法TextWatcher
也EditText
行不通,因为TextInputLayout
它没有暴露任何实际处理动画的内部结构 - 也没有updateLabelVisibility()
, setEditText()
,做这项工作的魔法Handler
或其他任何东西。当然,我们当然不想为这样的细节走反射路径,所以......
只需使用MaterialEditText!它具有以下属性,可以完全满足您的要求。
met_floatingLabelAlwaysShown : 总是显示浮动标签,而不是动画它进/出。默认为假。
该库非常稳定(我自己在两个不同的项目中使用它)并且有很多自定义选项。希望能帮助到你!
尽管有最佳答案,但我仍然简单地提出了一个 Java 反射解决方案来实现所需的行为(使用com.google.android.material.textfield.TextInputLayout
from 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;
}
对于支持设计 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"
/>
新属性app:expandedHintEnabled
(从 1.3.0 开始)解决了这个问题,无需子类化和其他 hack。
https://github.com/material-components/material-components-android/issues/810
这是您可以使用的一个技巧,它将允许您将标签提示放在布局中,并将文本框提示放在编辑文本中,而不会发生冲突。它也将比上述反射解决方案更好地工作,因为它可以防止发生原始不良绘图并且不需要您解决缩小/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>