问题说明:本人刚接触安卓开发不是很久,在练习的过程中遇到了输入法的隐藏和弹出的问题,想让输入法软键盘在合适的时候进行显示和隐藏。经过查询各种资料和亲身测试,总结了这个小的技巧,在这里和大家分享一下。有不正确的请大家指正。
1.创建安卓项目之后,编写需要用到EditText的布局文件,如下:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"
android:id="@+id/all_layout"
tools:context="${relativePackage}.${activityClass}" >
<TextView
android:id="@+id/head"
android:layout_width="match_parent"
android:layout_height="40sp"
android:text="@string/hello_world"
android:background="#3399FF"
android:textSize="20sp"
android:textColor="#FFFFFF"
android:gravity="center" />
<TextView
android:id="@+id/name"
android:layout_height="50sp"
android:layout_width="80sp"
android:layout_below="@id/head"
android:layout_marginTop="2sp"
android:text="@string/name"
android:textSize="20sp"
android:gravity="center"/>
<EditText
android:id="@+id/enterName"
android:layout_height="50sp"
android:layout_width="match_parent"
android:layout_marginTop="2sp"
android:hint="@string/enterName"
android:background="@drawable/bg_edittext"
android:gravity="center"
android:layout_toRightOf="@id/name"
android:layout_toEndOf="@id/name"
android:layout_below="@id/head"
android:focusableInTouchMode="true"
android:focusable="true"/>
<TextView
android:id="@+id/age"
android:layout_height="50sp"
android:layout_width="80sp"
android:layout_below="@id/name"
android:layout_marginTop="2sp"
android:text="@string/age"
android:textSize="20sp"
android:gravity="center"/>
<EditText
android:id="@+id/enterAge"
android:layout_height="50sp"
android:layout_width="match_parent"
android:layout_marginTop="2sp"
android:hint="@string/enterAge"
android:background="@drawable/bg_edittext"
android:gravity="center"
android:layout_toRightOf="@id/age"
android:layout_toEndOf="@id/age"
android:layout_below="@id/enterName"/>
<TextView
android:id="@+id/height"
android:layout_height="50sp"
android:layout_width="80sp"
android:layout_below="@id/age"
android:layout_marginTop="2sp"
android:text="@string/height"
android:textSize="20sp"
android:gravity="center"/>
<EditText
android:id="@+id/enterHei"
android:layout_height="50sp"
android:layout_width="match_parent"
android:layout_marginTop="2sp"
android:hint="@string/enterHeight"
android:background="@drawable/bg_edittext"
android:gravity="center"
android:layout_toRightOf="@id/name"
android:layout_toEndOf="@id/name"
android:layout_below="@id/enterAge"/>
<TextView
android:id="@+id/Id_id"
android:layout_height="40sp"
android:layout_width="80sp"
android:layout_below="@id/add"
android:layout_marginTop="2sp"
android:text="@string/Id"
android:textSize="20sp"
android:gravity="center"/>
<EditText
android:id="@+id/enterId"
android:layout_height="40sp"
android:layout_width="match_parent"
android:layout_marginTop="2sp"
android:hint="@string/enterId"
android:background="@drawable/bg_edittext"
android:gravity="center"
android:layout_toRightOf="@id/Id_id"
android:layout_toEndOf="@id/Id_id"
android:layout_below="@id/showAll"/>
</RelativeLayout>
以上需要注意的是,我这里用到的是让布局能够获得焦点,从而达到和输入框抢焦点,隐藏输入法的目的。就是在刚刚进入这个页面时不让输入法直接弹出,需要手动点击输入框才会弹出输入法
在相对布局的设置中加入了两句:
android:focusable="true"
android:focusableInTouchMode="true"
以前本人在测试时增加过clickable属性,后来发现会点击两次才会隐藏输入法,所以为了提升体验,就删去了。有兴趣的可以试试看。
让布局可以获得焦点
2.接下来就是在java文件中对界面进行监听
MainActivity.java
package com.example.androidexperimentfive;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.view.Window;
import android.widget.EditText;
public class MainActivity extends Activity{
private EditText name_et;
private EditText age_et;
private EditText height_et;
private EditText id_et;
private int name_etleft, name_ettop, name_et_bottom, name_et_right;
private int age_etleft, age_ettop, age_et_bottom, age_et_right;
private int height_etleft, height_ettop, height_et_bottom, height_et_right;
private int id_etleft, id_ettop, id_et_bottom, id_et_right;
//记录是否计算过本页面各个输入框的位置
private static boolean registeOpenCount = false;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//去除主页面的Title
setContentView(R.layout.activity_main);
initView();
}
public void initView() {
name_et = (EditText) findViewById(R.id.enterName);
age_et = (EditText) findViewById(R.id.enterAge);
height_et = (EditText) findViewById(R.id.enterHei);
id_et = (EditText) findViewById(R.id.enterId);
}
// 隐藏输入法算法
// 重写dispachTouchEvent方法进行判定什么时候进行隐藏
public boolean dispatchTouchEvent(MotionEvent ev) {
if (!registeOpenCount) {
calculateEtXY();
registeOpenCount = true;
}
if (ev.getAction() == MotionEvent.ACTION_DOWN){
return super.dispatchTouchEvent(ev);
}
else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
return super.dispatchTouchEvent(ev);
}
else if (ev.getAction() == MotionEvent.ACTION_UP) {
boolean b = false;
View v = getCurrentFocus();
float x = ev.getX();
float y = ev.getY();
b = isAlsoET(x, y);
if (!b) {//如果点击的位置不是输入框
if (v instanceof EditText)
v.clearFocus();//如果当前获得焦点的是输入框EditText,就清除焦点
InputMethodManager imm = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
return super.dispatchTouchEvent(ev);
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
// 判断点击的区域是否是文本框
public boolean isAlsoET(float x, float y) {
if ((x > name_etleft) && (y > name_ettop) && (x < name_et_right) && (y < name_et_bottom))
return true;
if ((x > age_etleft) && (y > age_ettop) && (x < age_et_right) && (y < age_et_bottom))
return true;
if ((x > height_etleft) && (y > height_ettop) && (x < height_et_right) && (y < height_et_bottom))
return true;
if ((x > id_etleft) && (y > id_ettop) && (x < id_et_right) && (y < id_et_bottom))
return true;
return false;
}
// 事先计算好所有EditText的x,y坐标,用到的时候不用重复计算
public void calculateEtXY() {
int[] name_etleftTop = { 0, 0 };
name_et.getLocationInWindow(name_etleftTop);
name_etleft = name_etleftTop[0];
name_ettop = name_etleftTop[1];
name_et_bottom = name_ettop + name_et.getHeight();
name_et_right = name_etleft + name_et.getWidth();
int[] age_etleftTop = { 0, 0 };
age_et.getLocationInWindow(age_etleftTop);
age_etleft = age_etleftTop[0];
age_ettop = age_etleftTop[1];
age_et_bottom = age_ettop + age_et.getHeight();
age_et_right = age_etleft + age_et.getWidth();
int[] height_etleftTop = { 0, 0 };
height_et.getLocationInWindow(height_etleftTop);
height_etleft = height_etleftTop[0];
height_ettop = height_etleftTop[1];
height_et_bottom = height_ettop + height_et.getHeight();
height_et_right = height_etleft + height_et.getWidth();
int[] id_etleftTop = { 0, 0 };
id_et.getLocationInWindow(id_etleftTop);
id_etleft = id_etleftTop[0];
id_ettop = id_etleftTop[1];
id_et_bottom = id_ettop + id_et.getHeight();
id_et_right = id_etleft + id_et.getWidth();
}
}
上面的代码中隐藏输入法的关键代码是
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
是隐藏输入法的能够实现语句。之前查过一些资料,也有很多说法,试了多次发现这个是可以使用的。我加入了一些改进的比较实用的小东西。
其中isAlsoET(float x, float y)是判断点击位置是否是EditText,calculateEtXY()是获取当前页面中所有EditText的位置,这段代码会在当界面有多个EditText时,从一个点击到另外一个不会频繁的隐藏和弹出软键盘。
本人新人上手,欢迎交流,有不对之处还请指出,谢谢。