【关键词】
EditText
输入法
获得焦点
失去焦点
【问题】
- 默认是居中显示且非编辑状态,点击 EditText后文字居左且显示编辑状态;
- 编辑状态时, 点击屏幕其他地方,使其失去焦点;
- 进入界面时 EditText 获取焦点问题(默认状态下不获取焦点);
- 非编辑状态无底线,编辑状态有底线加以区分;
【效果图】
【分析】
- 见源码及注释;
【解决方案】
- 默认让包含 EditText 的 ViewGroup 获取焦点;
【代码】
[java activity]
private void initEtName() {
// 使RelativeLayout 获取焦点,防止 EditText 截取
final RelativeLayout rlytTimerName = (RelativeLayout) findViewById(R.id.rlyt_timer_name);
rlytTimerName.setFocusable(true);
rlytTimerName.setFocusableInTouchMode(true);
rlytTimerName.requestFocus();
final EditText etName;
etName = (EditText) findViewById(R.id.et_name);
etName.setOnClickListener(this);
etName.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
etNameGetFocus(etName);
} else {
etNameLostFocus(etName);
}
}
});
String name = "Lou";
etName.setText(name);
etNameLostFocus(etName);
}
// 重置edittext, 居中并失去焦点
private void etNameLostFocus(EditText etName) {
etName.setGravity(Gravity.CENTER);
etName.clearFocus();
InputMethodManager manager = (InputMethodManager) etName.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
manager.hideSoftInputFromWindow(etName.getWindowToken(), 0);
}
// 获取焦点
private void etNameGetFocus(final EditText etName) {
etName.requestFocus();
etName.setGravity(Gravity.START);
etName.post(new Runnable() {
@Override
public void run() {
InputMethodManager manager = (InputMethodManager) etName.getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
manager.showSoftInput(etName, 0);
}
});
// 光标置于文字最后
etName.setSelection(etName.getText().length());
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.et_name:
// 设置 EditText 的点击事件(如果处于编辑状态则,不做操作;否则,获取焦点进入可编辑状态);
EditText et = (EditText) v;
if (!et.isCursorVisible()) {
etNameGetFocus(et);
}
break;
}
}
// 点击屏幕其他地方,使 etName 失去焦点(EditText)
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
// 获取当前焦点所在的控件;
View view = getCurrentFocus();
if (view != null && view instanceof EditText) {
Rect r = new Rect();
view.getGlobalVisibleRect(r);
int rawX = (int) ev.getRawX();
int rawY = (int) ev.getRawY();
// 判断点击的点是否落在当前焦点所在的 view 上;
if (!r.contains(rawX, rawY)) {
view.clearFocus();
}
}
}
return super.dispatchTouchEvent(ev);
}
[xml layout]
<RelativeLayout
android:id="@+id/rlyt_timer_name"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_width="match_parent"
android:orientation="horizontal">
<EditText
android:background="@drawable/et_name"
android:hint="Please input your name"
android:id="@+id/et_name"
android:layout_centerVertical="true"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:maxLength="15"
android:maxLines="1"
android:paddingBottom="4dp"
android:paddingStart="8dp"
android:paddingTop="4dp"
android:text="Hello World"
android:textColor="@color/module_title_font"
android:textCursorDrawable="@null"
android:textSize="18sp"></EditText>
</RelativeLayout>
[et_name.xml]
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true">
<layer-list>
<item >
<shape android:shape="rectangle">
<solid android:color="@color/module_title_font"/>
</shape>
</item>
<item android:bottom="8dp">
<shape android:shape="rectangle">
<solid android:color="@color/main_content_bg"/>
</shape>
</item>
<item android:bottom="1dp" android:left="1dp" android:right="1dp">
<shape android:shape="rectangle">
<padding android:left="2dp" android:right="2dp"/>
<solid android:color="@color/main_content_bg"/>
</shape>
</item>
</layer-list>
</item>
</selector>
[colors.xml]
<color name="module_title_font">#c2c2c1</color>
<color name="main_content_bg">#3c3c3b</color>