如果editText位于TextInputlayout内,则将drawableLeft添加到EditText会将提示向右移动 [英] Adding a drawableLeft to an EditText shifts the hint towards right, if edittext is inside TextInputlayout
问题描述
我已经在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
前缀表示法.如评论中所述,它们现在分别命名为collapsingTextHelper
和collapsedBounds
.
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 namedcollapsingTextHelper
andcollapsedBounds
, respectively.
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屋!