如何让Android EditText的提示居中并将光标放在左侧

13
如何将提示文本设置在EditText的中心,并将光标设置在EditText的左侧?当我开始输入文本时,它会从EditText的中心开始吗?

enter image description here

现在我有

enter image description here

<LinearLayout
                android:orientation="horizontal"
                android:layout_width="fill_parent"
                android:layout_height="match_parent"
                android:background="@drawable/line_white"
                android:layout_marginBottom="25dp"
                android:paddingBottom="16dp"
                android:gravity="center_horizontal">

                <EditText
                    android:id="@+id/loginEmailField"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:autoText="false"
                    android:ems="10"
                    android:hint="Choose an email adress"
                    android:inputType="textEmailAddress"
                    android:paddingLeft="2dp"
                    android:singleLine="false"
                    android:textColor="#ffffff"
                    android:textColorHint="#9377ab"
                    android:textSize="19sp"
                    android:textStyle="bold"
                    android:background="#00000000"
                    android:layout_marginRight="2dp"
                    android:gravity="center"/>
            </LinearLayout>
9个回答

6

这是一个有些愚蠢的问题,我知道... 解决这个问题最简单的方法(并保持文本居中)是使用这个简单的技巧:

        editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {}
        @Override
        public void afterTextChanged(Editable s) {
            if (s != null && s.toString().length() > 0){
                editText.setGravity(Gravity.CENTER);
            }else{
                editText.setGravity(Gravity.START);
            }
        }
    });

1
那应该是经过验证的答案。 - Geoffroy CALA

3

我也面对同样的问题,想到了两种可能的解决方案:

1. 相当简单
在提示信息中间的光标看起来有点不舒服。
所以,我只需要在editText获得焦点时删除提示信息,否则就将其设置回去:

editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        editText.setHint(hasFocus ? "" : "My hint");
    }
});

2. 一些硬编码
在这种情况下:
如果editText为空:
- 设置文本为提示语
- 将文本颜色设置为提示文本颜色
- 禁用选择文本
- 将光标设置在文本之前(setSelection(0)

如果用户输入任何符号
- 用空白替换提示语
- 将文本颜色设置回文本颜色
- 启用选择文本

步骤:
2.1 添加TextWatcher

editText.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { // empty }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) { // empty }

    @Override
    public void afterTextChanged(Editable s) { 
        processChangedText(s); 
    }
});

2.2 设置焦点改变监听器:

editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
       if (hasFocus) {
           processChangedText(editText.getText());
       }
    }
});

2.3 在方法processChangedText(Editable s)中有一些小魔法

private void processChangedText(Editable s) {
    String str = s.toString();
    final int colorHint = ContextCompat.getColor(getActivity(), R.color.color_hint);
    final int colorText = ContextCompat.getColor(getActivity(), R.color.color_text);

    String hint = getString(R.string.login_login_edit_hint);
    if (str.equals(hint)) {
        editText.setTextColor(colorHint);
        enableCursorMove(editText, false);
        editText.setSelection(0);
        return;
    } else {
        editText.setTextColor(colorText);
        enableCursorMove(editText, true);
    }
    if (str.isEmpty()) {
        editText.setText(hint);
    } else if (str.contains(hint)) {
        editText.setText(str.replace(hint, ""));
    } else if (str.length() == 1) {
        editText.setSelection(1);
    }
}

2.4 启用/禁用光标移动方式(可能不是一个好选择,最好创建自己的EditText,并覆盖onSelectionChanged方法)

private void enableCursorMove(EditText editText, boolean enable) {
    editText.setOnTouchListener(enable ? null : new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            editText.setSelection(0);
            return true;
        }
    });
}

附注:我强烈建议您使用第一种方法,它非常简单且看起来很好。


3
EditText获取焦点时,您可以隐藏提示。
使用我的自定义EditText:
https://gist.github.com/repitch/2ca5b01a842609cfe26f3a41f825a300
public class HintHideEditText extends EditText {

    private CharSequence savedHint;

    public HintHideEditText(Context context) {
        super(context);
    }

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

    public HintHideEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        validateHint(focused);
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
    }

    public CharSequence getSavedHint() {
        return savedHint;
    }

    public void setSavedHint(CharSequence savedHint) {
        this.savedHint = savedHint;
        validateHint(hasFocus());
    }

    public void setSavedHint(@StringRes int resid) {
        setSavedHint(getContext().getResources().getText(resid));
    }

    private void validateHint(boolean focused) {
        if (focused) {
            savedHint = getHint();
        }
        setHint(focused ? "" : savedHint);
    }

}

虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅链接的答案可能会失效。- 来自审查 - Bö macht Blau
1
@0x0nosugar,已修复。 - repitch

1
将以下代码放入您的代码中,一旦您已经填充了视图:
EditText editText = (EditText)findViewById(R.id.loginEmailField);
editText.setSelection(0);

它将把插入符号放在您的提示文本开头。一旦您开始输入,文本将保持居中,插入符号将移动到您正在输入的末尾。

0

您可以在编辑文本下方添加额外的View来模拟编辑文本行,将编辑文本背景设置为null,宽度设置为wrap_content,并将layout_gravity设置为中心。

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:background="@null"
        android:cursorVisible="true"
        android:ellipsize="start" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#ffffff" />
</LinearLayout>

0
在xml中,EditText必须有android:layout_width="wrap_content"属性。
然后,将代码设置为以下内容:
final EditText msgTxt = (EditText) view.findViewById(R.id.edtTxt);

msgTxt.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        if(s.length() != 0){
            msgTxt.setGravity(Gravity.CENTER);
        }
        else{
            msgTxt.setGravity(Gravity.CENTER_VERTICAL);
        }
    }
});

0

不要使用编辑文本的提示:

  1. 将透明度添加到EditText的背景颜色中
  2. 在EditText后面直接添加一个新的TextView - 将其文本设置为提示的文本。
  3. 在EditText中设置gravity="left" - 这样光标将位于视图的左侧。

将两个视图(EditText和TextView)放置在RelativeLayout中 - 这样您就可以将提示视图定位在TextView后面。


0

没有直接的方法来实现它,但您可以尝试使用以下代码

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="48dp">
    <EditText
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:layout_gravity="center"
        android:hint="You text here"/>
</FrameLayout>

给父FrameLayout设置下划线背景,当单击它时将焦点放在EditText上。

我说尝试一下,并不意味着你应该给别人投反对票。 - Narendra Kothamire

-1

试试我的代码:

android:textCursorDrawable="@null"

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