EditText 是一个非常重要的组件,可以说是用户和 Android 应用进行数据传输的窗户:用户可以把数据传给应用,然后得到想要的数据。EditText 是 TextView 的子类,所以 TextView 的方法和特性同样存在于 EditText 中。
学习内容:1. 常用属性;2. 文本监听 TextChangedListener;3. 错误提示 setError;4. 自定义样式。
一、长度、hint 与是否可编辑
EditText 有一些属性可以设置特性,比如最大长度、空白提示文字等。有时只能输入特定个数的字符,比如身份证号、手机号码,这时可以用 android:maxLength 设置最大输入字符个数,例如 android:maxLength="4" 就表示最多能输入 4 个字符,再多就输入不进去了。
空白提示文字:需要说明这个 EditText 是做什么用的,比如输入「用户名」或「电话号码」,又不想在前面加一个 TextView。EditText 提供了 android:hint 来设置内容为空时显示的文本,输入字符后就消失,不影响真正的文本。修改 main.xml 如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
android:id="@+id/edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:maxLength="40"
android:hint="请输入用户名..."/>
</LinearLayout>
如果不想要灰色提示文字,可以通过 android:textColorHint 换颜色:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
android:id="@+id/edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:maxLength="40"
android:hint="请输入用户名..."
android:textColorHint="#238745"/>
</LinearLayout>
还有一个比较实用的功能:设置不可编辑。android:enabled="false" 可以实现不可编辑,但可以获得焦点。这时 EditText 和一个 TextView 差不多。
二、输入特殊格式的字符
开发时不免要输入密码(掩码显示)、电话号码(数字和 -)、数字等特殊格式。强大的 EditText 同样提供了这些设置。
密码文本框:配置 android:password="true" 即可。输入的字符会被「.」这样的掩码代替:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
android:id="@+id/edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:password="true"/>
</LinearLayout>
专门输入电话号码:设置 android:phoneNumber="true" 就可以把 EditText 变成只接受电话号码的文本框,连软键盘都变成拨号专用,不用再担心输入其他字符:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
android:id="@+id/edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:phoneNumber="true"/>
</LinearLayout>
只想输入数字:用 android:numeric 控制数字类型,一共三种:integer(正整数)、signed(带符号整数)和 decimal(浮点数)。以 signed 为例,软键盘会变成数字键盘:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
android:id="@+id/edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:numeric="signed"/>
</LinearLayout>
三、为文本指定软键盘类型
前面指定电话号码后键盘会自动变成拨号键盘。也可以通过 android:inputType 设置文本类型,让输入法选择合适的软键盘。inputType 有很多类型,这里用 date 演示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
android:id="@+id/edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="date"/>
</LinearLayout>
四、Enter 键图标(imeOptions)
软键盘的 Enter 键默认显示「完成」。按 Enter 表示前置工作准备完毕,例如搜索时希望显示「搜索」或搜索图标。通过 android:imeOptions 可以改变默认的「完成」文本。常用常量值:
-
actionUnspecified 未指定,对应 EditorInfo.IME_ACTION_UNSPECIFIED
-
actionNone 没有动作,对应 EditorInfo.IME_ACTION_NONE
-
actionGo 去往,对应 EditorInfo.IME_ACTION_GO
-
actionSearch 搜索,对应 EditorInfo.IME_ACTION_SEARCH
-
actionSend 发送,对应 EditorInfo.IME_ACTION_SEND
-
actionNext 下一个,对应 EditorInfo.IME_ACTION_NEXT
-
actionDone 完成,对应 EditorInfo.IME_ACTION_DONE
下面以搜索为例:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
android:id="@+id/edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:imeOptions="actionSearch"/>
</LinearLayout>
HelloEditText 如下。运行后点击回车(搜索图标软键盘按钮)会显示该 actionId,对应上面每个设置的常量值:
package com.flysnow;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.TextView.OnEditorActionListener;
public class HelloEditText extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
EditText editText=(EditText)findViewById(R.id.edit_text);
editText.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
Toast.makeText(HelloEditText.this, String.valueOf(actionId), Toast.LENGTH_SHORT).show();
return false;
}
});
}
}
五、取值、全选、部分选择、获取选中文本
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
android:id="@+id/edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:imeOptions="actionSearch"/>
<Button
android:id="@+id/btn_get_value"
android:text="取值"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btn_all"
android:text="全选"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btn_select"
android:text="从第2个字符开始选择"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btn_get_select"
android:text="获取选中文本"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
HelloEditText 修改如下:
import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.Selection;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.TextView.OnEditorActionListener;
/**
* EditText演示
* @since 2010-11-29
*/
public class HelloEditText extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final EditText editText=(EditText)findViewById(R.id.edit_text);
//监听回车键
editText.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
Toast.makeText(HelloEditText.this, String.valueOf(actionId), Toast.LENGTH_SHORT).show();
return false;
}
});
//获取EditText文本
Button getValue=(Button)findViewById(R.id.btn_get_value);
getValue.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(HelloEditText.this, editText.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
//让EditText全选
Button all=(Button)findViewById(R.id.btn_all);
all.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
editText.selectAll();
}
});
//从第2个字符开始选择EditText文本
Button select=(Button)findViewById(R.id.btn_select);
select.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Editable editable=editText.getText();
Selection.setSelection(editable, 1,editable.length());
}
});
//获取选中的文本
Button getSelect=(Button)findViewById(R.id.btn_get_select);
getSelect.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int start=editText.getSelectionStart();
int end=editText.getSelectionEnd();
CharSequence selectText=editText.getText().subSequence(start, end);
Toast.makeText(HelloEditText.this, selectText, Toast.LENGTH_SHORT).show();
}
});
}
/**
* 交换两个索引
* @param start 开始索引
* @param end 结束索引
*/
protected void switchIndex(int start, int end) {
int temp=start;
start=end;
end=temp;
}
}
六、TextInputLayout 浮动标签
要使用 TextInputLayout 控件,需要导入两个 Library。第一个是 appcompat-v7,确保 material style 可以向后兼容;第二个是 Design Support Library。在 build.gradle 中添加依赖:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
}
布局文件中使用参考如下:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="输入用户名:"
android:inputType="textEmailAddress" />
<android.support.design.widget.TextInputLayout
android:id="@+id/passwordWrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="输入密码:"
android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/login_demo_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="Login" />
</LinearLayout>
获取输入框 EditText 内容可以直接用 TextInputLayout 实例获取:
final TextInputLayout passwordWrapper = (TextInputLayout) findViewById(R.id.passwordWrapper);
String password = passwordWrapper.getEditText().getText().toString();
显示错误信息:
passwordWrapper.setError("Not a valid password!");
参考:http://www.jcodecraeer.com/a/basictutorial/2015/0821/3338.html
| 需求 |
属性 / API |
| 限制长度 |
android:maxLength |
| 空内容提示 |
android:hint、android:textColorHint |
| 不可编辑 |
android:enabled=”false” |
| 密码 / 电话 / 数字 |
android:password、phoneNumber、numeric |
| 软键盘类型 |
android:inputType(如 date) |
| Enter 键文案 |
android:imeOptions + OnEditorActionListener |
| 取值与选区 |
getText、selectAll、Selection.setSelection、getSelectionStart/End |
| 浮动标签与错误 |
TextInputLayout.getEditText()、setError |
一句话总结:EditText 用 maxLength、hint、password/inputType/imeOptions 管输入体验,再用 getText 和选区 API 取值;Material 下用 TextInputLayout 做浮动标签和错误提示。