触摸屏幕取消键盘

当点击文本框和发送按钮的时候不需要取消键盘,点击屏幕其他按钮或者其他控件的时候消失键盘
[size=large]解决方案一:[/size]

为了测试,把父布局设置成可点击可获取交点的。如下:
<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:clickable="true"
tools:context=".MainActivity" >

<LinearLayout
android:id="@+id/ll"
android:background="#11ff0000"
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >

<EditText
android:id="@+id/et"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="8" />

<Button
android:id="@+id/bt"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:text="发送" />
</LinearLayout>

</RelativeLayout>

[size=x-large]主要逻辑代码如下:[/size]
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ll = (LinearLayout) findViewById(R.id.ll);
EditText et = (EditText) findViewById(R.id.et);
Button bt = (Button) findViewById(R.id.bt);
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
// View v = getCurrentFocus();
View v = ll;
if (isShouldHideKeyboard(v, ev)) {
hideKeyboard(v.getWindowToken());
}
}
return super.dispatchTouchEvent(ev);
}

/**
* 根据EditText所在坐标和用户点击的坐标相对比,来判断是否隐藏键盘,因为当用户点击EditText时则不能隐藏
*/
private boolean isShouldHideKeyboard(View v, MotionEvent event) {
if (v != null) {// 如果点击的是edittext
int[] l = { 0, 0 };
v.getLocationInWindow(l);// 获取v在窗口中的位置
int left = l[0], top = l[1], bottom = top + v.getHeight(), right = left
+ v.getWidth();
// 判断点击的是不是在v的区域里面
System.out.println("位置:(" + left + "," + top + ")(" + right + ","
+ bottom + ")");
System.out.println("event-x:" + event.getX());
System.out.println("event-y:" + event.getY());
if (event.getX() > left && event.getX() < right
&& event.getY() > top && event.getY() < bottom) {
// 点击的位置在v区域里面
return false;
} else {
return true;
}
}
// 如果焦点不是EditText则忽略,这个发生在视图刚绘制完,第一个焦点不在EditText上,和用户用轨迹球选择其他的焦点
return false;
}

/**
* 获取InputMethodManager,隐藏软键盘
*
* @param token
*/
private void hideKeyboard(IBinder token) {
if (token != null) {
InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
im.hideSoftInputFromWindow(token,
InputMethodManager.HIDE_NOT_ALWAYS);
}
}

/**
* 点击空白位置 隐藏软键盘
*/
public boolean onTouchEvent(MotionEvent event) {
if (null != this.getCurrentFocus()) {
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
return mInputMethodManager.hideSoftInputFromWindow(this
.getCurrentFocus().getWindowToken(), 0);
}
return super.onTouchEvent(event);
}

经过测试发现,当弹出键盘的时候点击输入框仍然会取消键盘然后再次弹出键盘。这个问题是因为当弹起键盘的时候键盘会挤压屏幕,导致点击的坐标被判断在指定的布局之外所以就取消键盘,但同时输入框获取了焦点所以又再次弹出键盘,解决这个问题只需要让屏幕不被键盘挤压即可,代码如下:
<activity
android:name="com.example.touchdissmis.MainActivity"
android:windowSoftInputMode="adjustResize"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>


[size=x-large]解决方案二:[/size]
获取相对于屏幕的点击位置和控件位置,即将getX(),getY()改成getRawX(),getRawY()。
getX()是表示Widget相对于自身右上角的x坐标二getRawX()是表示相对于屏幕左上角的x坐标值(注意:这个屏幕右上角是手机屏幕右上角,不管Activity是否有titleBar或者是全屏),getY(),getRawY()一样的道理。
代码如下:
不限制屏幕滚动:
<activity
android:name="com.example.touchdissmis.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>


修改获取坐标的方法:

本例中使用v.getLocationInWindow或者是 v.getLocationOnScreen都行,是因为屏幕中就一个界面。所以两种方法获取的位置一样,最后有观月这两个方法的区别

private boolean isShouldHideKeyboard(View v, MotionEvent event) {
if (v != null) {//如果点击的是edittext
int[] l = { 0, 0 };
v.getLocationOnScreen(l);//获取v在窗口中的位置
int left = l[0], top = l[1], bottom = top + v.getHeight(), right = left + v.getWidth();
//判断点击的是不是在v的区域里面
System.out.println("位置:("+left+","+top+")("+right+","+bottom+")");
System.out.println("event-x:"+event.getRawX());
System.out.println("event-y:"+event.getRawY());
if (event.getRawX() > left && event.getRawX() < right&& event.getRawY() > top && event.getRawY() < bottom) {
// 点击的位置在v区域里面
return false;
} else {
return true;
}
}
// 如果焦点不是EditText则忽略,这个发生在视图刚绘制完,第一个焦点不在EditText上,和用户用轨迹球选择其他的焦点
return false;
}

[size=x-large]getLocationInWindow与getLocationOnScreen的区别[/size]
getLocationInWindow
一个控件在其父窗口中的坐标位置
getLocationOnScreen
一个控件在其整个屏幕上的坐标位置
getLocationInWindow是以B为原点的C的坐标,而getLocationOnScreen以A为原点。
int[] location = new int[2] ;
view.getLocationInWindow(location); //获取在当前窗口内的绝对坐标
view.getLocationOnScreen(location);//获取在整个屏幕内的绝对坐标
location [0]--->x坐标,location [1]--->y坐标
getLocationOnScreen
计算该视图在全局坐标系中的x,y值,(注意这个值是要从屏幕顶端算起,也就是索包括了通知栏的高度)//获取在当前屏幕内的绝对坐标
getLocationInWindow ,计算该视图在它所在的widnow的坐标x,y值,//获取在整个窗口内的绝对坐标
getLeft , getTop, getBottom,getRight, 这一组是获取相对在它父亲里的坐标

转载请注明出处:[url]http://renyuan-1991.iteye.com/blog/2248876[/url]
希望爱好编程的小伙伴能加这个群,互相帮助,共同学习。群号: 141877583
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值