TextInputLayout 标签锚定在 EditText 的左侧可绘制对象上方
TextInputLayout label to achor above the left drawable of an EditText
当用户聚焦或输入 EditText 时,是否可以使 TextInputLayout 标签垂直显示在 EditText 的左侧可绘制对象上方。
这里是 EditText 的xml:
<android.support.design.widget.TextInputLayout
android:id="@+id/completion_date_layout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:orientation="horizontal">
<EditText
android:id="@+id/etTaskDate"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/title_completion_date"
android:inputType="text"
android:drawableLeft="@drawable/ic_date"
android:paddingBottom="15dp"
android:drawablePadding="5dp"
android:textSize="@dimen/fields_text_size"/>
</android.support.design.widget.TextInputLayout>
这是所需的输出:
这是我得到的输出:
我已经针对此问题制定了解决方法。它可能有点不可靠,但它对我有用。
这是代码:
String spacer=" ";
EditText myEditText= (EditText)findViewById(R.id.myEditText);
myEditText.setText(spacer + "Today");
myEditText.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_calendar, 0, 0, 0);
我在这里所做的是在 editText 中的文本之前放置一个间隔符,然后以编程方式添加左侧的可绘制对象。
但请确保在获取 editText 的内容之前删除这些空格:
String title = myEditText.getText().toString().substring(8);
这意味着我裁剪了单词 "Today" 之前的 8 个空格。
您可以使用动画和 frame_layout 为左侧图标设置动画,尝试 this link,可能对您有所帮助。
感谢 Java 的成员访问模型和 Google 的开发人员留下了一个小漏洞,它可以通过一个简单的 subclassing 来实现,它至少重复原代码:
package android.support.design.widget;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
public final class TextInputLayoutEx extends TextInputLayout {
private final int mDefaultPadding = __4DP__;
private final Rect mTmpRect = new Rect();
public TextInputLayoutEx(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (isHintEnabled() && mEditText != null) {
final Rect rect = mTmpRect;
ViewGroupUtils.getDescendantRect(this, mEditText, rect);
mCollapsingTextHelper.setCollapsedBounds(
rect.left + mDefaultPadding, getPaddingTop(),
rect.right - mDefaultPadding, bottom - top - getPaddingBottom());
mCollapsingTextHelper.recalculate();
}
}
}
这里我们将一个新的 class 放到同一个包中,它打开了对具有包级别可见性的 mCollapsingTextHelper
的访问,然后重复了原始 [=13= 中的部分代码] 管理字段名称定位的方法。 __4DP__
值是 4dp 值转换为像素,我很确定每个人都有一个实用方法。
在您的 xml 布局中,只需从 android.support.design.widget.TextInputLayout
切换到 android.support.design.widget.TextInputLayoutEx
,这样您的布局将如下所示:
<android.support.design.widget.TextInputLayoutEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Mobile">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_phone_black_24dp"
android:drawablePadding="4dp"/>
</android.support.design.widget.TextInputLayoutEx>
结果是
目前它适用于 com.android.support:design:25.3.1
你可以试试这个习惯class:找到
然后只需更改 xml
com.mycompany.myapp.CustomTextInputLayout
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();
}
}
}
当用户聚焦或输入 EditText 时,是否可以使 TextInputLayout 标签垂直显示在 EditText 的左侧可绘制对象上方。
这里是 EditText 的xml:
<android.support.design.widget.TextInputLayout
android:id="@+id/completion_date_layout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:orientation="horizontal">
<EditText
android:id="@+id/etTaskDate"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/title_completion_date"
android:inputType="text"
android:drawableLeft="@drawable/ic_date"
android:paddingBottom="15dp"
android:drawablePadding="5dp"
android:textSize="@dimen/fields_text_size"/>
</android.support.design.widget.TextInputLayout>
这是所需的输出:
这是我得到的输出:
我已经针对此问题制定了解决方法。它可能有点不可靠,但它对我有用。 这是代码:
String spacer=" ";
EditText myEditText= (EditText)findViewById(R.id.myEditText);
myEditText.setText(spacer + "Today");
myEditText.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_calendar, 0, 0, 0);
我在这里所做的是在 editText 中的文本之前放置一个间隔符,然后以编程方式添加左侧的可绘制对象。
但请确保在获取 editText 的内容之前删除这些空格:
String title = myEditText.getText().toString().substring(8);
这意味着我裁剪了单词 "Today" 之前的 8 个空格。
您可以使用动画和 frame_layout 为左侧图标设置动画,尝试 this link,可能对您有所帮助。
感谢 Java 的成员访问模型和 Google 的开发人员留下了一个小漏洞,它可以通过一个简单的 subclassing 来实现,它至少重复原代码:
package android.support.design.widget;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
public final class TextInputLayoutEx extends TextInputLayout {
private final int mDefaultPadding = __4DP__;
private final Rect mTmpRect = new Rect();
public TextInputLayoutEx(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (isHintEnabled() && mEditText != null) {
final Rect rect = mTmpRect;
ViewGroupUtils.getDescendantRect(this, mEditText, rect);
mCollapsingTextHelper.setCollapsedBounds(
rect.left + mDefaultPadding, getPaddingTop(),
rect.right - mDefaultPadding, bottom - top - getPaddingBottom());
mCollapsingTextHelper.recalculate();
}
}
}
这里我们将一个新的 class 放到同一个包中,它打开了对具有包级别可见性的 mCollapsingTextHelper
的访问,然后重复了原始 [=13= 中的部分代码] 管理字段名称定位的方法。 __4DP__
值是 4dp 值转换为像素,我很确定每个人都有一个实用方法。
在您的 xml 布局中,只需从 android.support.design.widget.TextInputLayout
切换到 android.support.design.widget.TextInputLayoutEx
,这样您的布局将如下所示:
<android.support.design.widget.TextInputLayoutEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Mobile">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_phone_black_24dp"
android:drawablePadding="4dp"/>
</android.support.design.widget.TextInputLayoutEx>
结果是
目前它适用于 com.android.support:design:25.3.1
你可以试试这个习惯class:找到
然后只需更改 xml
com.mycompany.myapp.CustomTextInputLayout
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();
}
}
}