当禁用时,缩略editText的内容

4

我有一个布局,其中用户填写EditText,然后稍后将其禁用以充当标准TextView。

问题是,这个EditText上的省略号永远不起作用。当文本过长无法完全显示时,我希望它在结尾处显示“...”,但我找不到任何方法使其起作用,也不知道为什么它不起作用。

这是我的布局:

<RelativeLayout
android:id="@+id/search_container"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_below="@+id/toolbar"
android:background="@drawable/bg_border_bot_clickable"
android:addStatesFromChildren="@+id/ic_edit"
android:animateLayoutChanges="true">

    <View
        android:layout_width="45dp"
        android:layout_height="45dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="5dp"
        android:layout_alignParentLeft="true"
        android:background="@drawable/ic_action_search"
        android:id="@+id/ic_search" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:textColorHint="@color/text_hint"
        android:hint="@string/search_hint"
        android:id="@+id/et_search"
        android:textColor="@android:color/white"
        android:inputType="text|textCapSentences"
        android:ellipsize="end"
        android:singleLine="true"
        android:lines="1"
        android:imeOptions="actionSearch"
        android:background="@drawable/transition_rounded_rectangle"
        android:layout_toLeftOf="@+id/ic_edit"
        android:layout_toRightOf="@+id/ic_search"
        />

<View
    android:layout_width="45dp"
    android:layout_height="45dp"
    android:layout_centerVertical="true"
    android:layout_alignParentRight="true"
    android:background="@drawable/ic_edit"
    android:id="@+id/ic_edit"
    android:visibility="gone"
    android:clickable="true"/>

有什么想法可以实现这个目标吗?
5个回答

8
将以下属性添加到您的EditText中,以使用省略号包装内容。
android:scrollHorizontally="true"
android:ellipsize="end"
android:singleLine="true"
android:editable="false"

如果您不想在XML中默认设置editable为false,您可以通过调用setKeyListener(null)来达到相同的效果。

editText.setKeyListener(null);

1
将键监听器设置为null就可以了!谢谢。说实话,我一开始不相信,但我想这也有一定的道理。 - Gyome
这个运行得很好!另外,要将其用作输入字段:在创建视图后保留 KeyListener,并在 OnFocusChanged 监听器中设置/删除它。 - dwemthy
1
@ChristianAbella,谢谢你。你的提示(editText.keyListener = null)对我非常有用(适用于Android API 23+)。我只是添加了一些算法,因为我需要在用户重新聚焦到该字段时,EditText可以再次正常工作而不带省略号。 - Thiengo

4
这是我的解决方案(我已经想到了):
XML:
<androidx.appcompat.widget.AppCompatEditText
    android:id="@+id/et2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_marginHorizontal="10dp"
    android:layout_marginTop="10dp"
    android:background="@drawable/selector_btn_check_red_grey"
    android:hint="Please enter characters"
    android:inputType="text"
    android:lines="1"
    android:paddingHorizontal="10dp"
    android:paddingVertical="5dp"
    android:text="就会角度打开的事开发的急啊看手机发就卡的房多少"
    android:textAllCaps="false"
    android:textColor="@color/red_500"
    android:textSize="15sp" />

java:

    //Initialize to non-editable state
    et2.setKeyListener(null);
    et2.setEllipsize(TextUtils.TruncateAt.END);//setEllipsize只对hint有效果

    et2.setOnFocusChangeListener((v, hasFocus) -> {
        if (hasFocus) {
            //Editable status
            et2.setEllipsize(null);
            et2.setKeyListener(new TextKeyListener(TextKeyListener.Capitalize.NONE, false));
        } else {
            //Not editable[enter image description here][1]
            et2.setKeyListener(null);
            et2.setEllipsize(TextUtils.TruncateAt.END);
        }
    });

2

我认为EditText不支持省略。解决方法之一是在EditText下方放置一个带有省略的TextView。最初将TextView的可见性设置为GONE。当你想禁用EditText时,将其可见性设置为GONE,将文本分配给TextView并将TextView的可见性设置为VISIBLE。


0

由于您已经使用过:

android:ellipsize="end"

还有一件事情需要添加。从你的Java文件中调用setSelected(true)

EditText edit = (EditText) findViewById(R.id.editTextId);
edit.setSelected(true);

给你的 EditText 设置 id 为 editTextId ;

 <EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/editTextId" />

0
经过多次测试,包括使用AppCompatEditText API,我可以说@ChristianAbela的解决方案无疑是在项目需要支持Android 23(Android Marshmallow)及以上版本的情况下能够正常工作的。
在我的情况下,当用户返回到该字段时,我还应该将字段EditText恢复为正常状态(editText.keyListener != null)。
因此,如果您不能将EditText锁定但仍需要显示省略号,则以下代码策略可能会有用。

1 - 支持类

首先,我将所有字段状态的hackcode构建到一个支持类中:
import android.text.method.KeyListener
import android.widget.EditText

/**
 * The purpose of this class is to allow saving the status of the fields
 * present in the "Search estimate" page.
 *
 * Thus, it is possible to use a business logic where the fields present
 * on this page show, when there is large content, ellipsis indicating
 * that the content is even larger.
 */
class FieldDataStatusHolder {

    private var procedureFieldText: String = ""
    private var procedureFieldKeyListener: KeyListener? = null

    private var locationFieldText: String = ""
    private var locationFieldKeyListener: KeyListener? = null

    fun holdData(
        unfocusedField: EditText,
        procedureField: EditText
    ) {
        if (unfocusedField == procedureField) {
            procedureFieldText = unfocusedField.text.toString()
            procedureFieldKeyListener = unfocusedField.keyListener
        } else {
            locationFieldText = unfocusedField.text.toString()
            locationFieldKeyListener = unfocusedField.keyListener
        }

        /**
         * This binding to null is necessary because this is the core of
         * the hackcode. This makes the editable View (EditText or
         * subclasses) no longer editable and so the ellipses appear at
         * the end of the field.
         */
        unfocusedField.keyListener = null
    }

    fun retrieveHoldenData(
        focusedField: EditText,
        procedureField: EditText
    ) {
        if (focusedField == procedureField && procedureFieldKeyListener != null) {
            focusedField.keyListener = procedureFieldKeyListener

            if (focusedField.text.isNotEmpty()) {
                focusedField.setText(procedureFieldText)
            }
        } else if (locationFieldKeyListener != null) {
            focusedField.keyListener = locationFieldKeyListener

            if (focusedField.text.isNotEmpty()) {
                focusedField.setText(locationFieldText)
            }
        }
    }
}

在上面的代码中,不要被包含前缀或后缀的属性和变量所困惑,例如“Procedure”和“Location”。
这是因为这些是指我应用代码的问题域的标签。
屏幕上有两个字段,“搜索过程”和“搜索位置”。
一旦用户从一个或两个字段中移除焦点,如果字段内容比字段本身长,则省略号应出现在视觉组件的末尾。
2 - Hackcode实例声明
在客户端类中,我懒惰地添加了声明(但您可以按照自己的意愿进行操作),并且在类范围而不是函数范围内。
private val fieldDataStatusHolder by lazy {
    FieldDataStatusHolder()
}

3 - 在OnFocusChangeListener上执行

因此,有必要在我已经创建的OnFocusChangeListener生成器方法中添加FieldDataStatusHolder实例的逻辑执行:

private fun getFieldFocusChangeListener() = View.OnFocusChangeListener { view, hasFocus ->
    
    // I do have lots of more domain code here.

    if (hasFocus) {
        fieldDataStatusHolder.retrieveHoldenData(
            focusedField = view as EditText,
            procedureField = etProcedureField
        )
    } else {
        fieldDataStatusHolder.holdData(
            unfocusedField = view as EditText,
            procedureField = etProcedureField
        )
    }
}

以下是使用此方法在字段上初始化监听器的示例:

etProcedureField.onFocusChangeListener = getFieldFocusChangeListener()
etLocationField.onFocusChangeListener = getFieldFocusChangeListener()

4 - XML中的视图

最后,需要为EditText添加以下属性和值:

  • android:ellipsize="end"
  • android:maxLines="1"

请注意,即使对于Android 23,我也不需要以下属性:

  • android:singleLine (已过时)
  • android:scrollHorizontally

另一个重要的点是......实际上,每个字段都使用以下可视组件:

  • TextInputLayout
  • TextInputEditText

TextInputLayout组件包含一个endIcon。因此,每当字段失去焦点以便出现省略号(Android API 31+)时,我还会隐藏endIcon

但这是一种算法,我不会在这里添加它,以避免答案变得更冗长。

是的,这里的代码不仅适用于EditText,而且适用于任何其子类。

结果

当前焦点的字段:

enter image description here

没有焦点的字段:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接