android升级到AppCompat v22.1.0后,onKeyDown 和 onKeyUp menu按键不能被触发的解决办法
来源:互联网 发布:php ruby perl python 编辑:程序博客网 时间:2024/05/18 18:52
今天在android studio下做重写onKeyDown修改menu按键功能的时候,发现代码没有问题,就是在点击menu按键的时候onKeyDown不能被触发,代码如下:
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { Log.i("Err", keyCode + event.toString()); <span style="white-space:pre"></span> if (keyCode == KeyEvent.KEYCODE_MENU) { Toast.makeText(this, keyCode + event.toString(), Toast.LENGTH_SHORT).show(); return true; } else { return super.onKeyDown(keyCode, event); } }此时依次按下 音量+,-,menu,back……按键的时候,其他按键都能被相应,都能够在logcat显示出日志,唯独menu按键不被监听,日志如下图
排除代码问题之后,大概认定是sdk的问题,经过google查询,在stackoverflow找到相同的问题以及解决方法,原文链接如下:http://stackoverflow.com/questions/29852303/upgraded-to-appcompat-v22-1-0-and-now-onkeydown-and-onkeyup-are-not-triggered-wh/29852304#
原文给出的解决方案解释是这样的,升级AppCompat v22.1.0之后,onKeyDown and onKeyUp方法中按下menu时候事件不被传播,唯一的解决方法是,在AppCompat 执行menu事件之前利用反射拦截onKeyDown和onKeyUp的事件,翻译的不准,见效了。
解决方法:
1.在自己项目添加如下类:
<span style="font-size:18px;">import android.support.v7.app.AppCompatActivity;import android.support.v7.internal.view.WindowCallbackWrapper;import android.view.KeyEvent;import android.view.Window;import java.lang.ref.WeakReference;import java.lang.reflect.Field;/** * Created by M星空 on 2015/5/7 0007. */public class AppCompatActivityMenuKeyInterceptor { private static final String FIELD_NAME_DELEGATE = "mDelegate"; private static final String FIELD_NAME_WINDOW = "mWindow"; public static void intercept(AppCompatActivity appCompatActivity) { new AppCompatActivityMenuKeyInterceptor(appCompatActivity); } private AppCompatActivityMenuKeyInterceptor(AppCompatActivity activity) { try { Field mDelegateField = AppCompatActivity.class.getDeclaredField(FIELD_NAME_DELEGATE); mDelegateField.setAccessible(true); Object mDelegate = mDelegateField.get(activity); Field mWindowField = mDelegate.getClass().getSuperclass().getSuperclass().getDeclaredField(FIELD_NAME_WINDOW); mWindowField.setAccessible(true); Window mWindow = (Window) mWindowField.get(mDelegate); Window.Callback mOriginalWindowCallback = mWindow.getCallback(); mWindow.setCallback(new AppCompatWindowCallbackCustom(mOriginalWindowCallback, activity)); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } private class AppCompatWindowCallbackCustom extends WindowCallbackWrapper { private WeakReference<AppCompatActivity> mActivityWeak; public AppCompatWindowCallbackCustom(Window.Callback wrapped, AppCompatActivity appCompatActivity) { super(wrapped); mActivityWeak = new WeakReference<AppCompatActivity>(appCompatActivity); } @Override public boolean dispatchKeyEvent(KeyEvent event) { final int keyCode = event.getKeyCode(); final int action = event.getAction(); AppCompatActivity appCompatActivity = mActivityWeak.get(); if (appCompatActivity != null) { if (keyCode == KeyEvent.KEYCODE_MENU && action == KeyEvent.ACTION_DOWN) { if (mActivityWeak.get().onKeyDown(event.getKeyCode(), event)) return true; } else if (keyCode == KeyEvent.KEYCODE_MENU && action == KeyEvent.ACTION_UP) { if (mActivityWeak.get().onKeyUp(event.getKeyCode(), event)) return true; } } return super.dispatchKeyEvent(event); } }}</span>
2.在activity的onCreate方法中添加如下代码:
AppCompatActivityMenuKeyInterceptor.intercept(this);
import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.util.Log;import android.view.KeyEvent;import android.view.Menu;import android.view.MenuItem;import android.widget.Toast;public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); AppCompatActivityMenuKeyInterceptor.intercept(this); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { Log.i("Err", keyCode + event.toString()); if (keyCode == KeyEvent.KEYCODE_MENU) { Toast.makeText(this, keyCode + event.toString(), Toast.LENGTH_SHORT).show(); return true; } else { return super.onKeyDown(keyCode, event); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); }}
至此,就解决了AppCompat v22.1.0 新版本onKeyDown 或者 onKeyUp menu事件不能够被传出的问题,但是这里遇到另外一个问题,如果activity有actionbar有三个点需要显示的menu的话,点击menu按键的时候,除了,会执行onKeyDown自定义的功能外,还会执行弹出actionbar菜单的功能,如下:
menu属性showAsAction="always"就行了,就是不要显示三个点的按钮在actionbar
0 0
- android升级到AppCompat v22.1.0后,onKeyDown 和 onKeyUp menu按键不能被触发的解决办法
- onkeypress和onkeydown以及onkeyup的区别
- onkeyup,onkeydown和onkeypress的区别介绍
- onkeyup,onkeydown和onkeypress的区别介绍
- onkeyup,onkeydown和onkeypress的区别介绍
- onkeyup,onkeydown和onkeypress
- onkeyup,onkeydown和onkeypress
- onkeyup,onkeydown和onkeypress
- onkeyup,onkeydown和onkeypress
- 转 : onkeyup,onkeydown和onkeypress
- onkeyup,onkeydown和onkeypress区别
- Android键盘操作的函数:onKeyDown, onKeyUp, on, onKeyMultiple
- onkeypress onkeyup onkeydown 的区别
- onkeypress,onkeyup,onkeydown的区别
- onkeyup,onkeydown,onkeypress的区别
- 使用.NET Compact Framework开发Windows Mobile程序,不能触发OnKeyPress/OnKeyDown的原因及解决办法
- 使用.NET Compact Framework开发Windows Mobile程序,不能触发OnKeyPress/OnKeyDown的原因及解决办法
- onkeypress、onkeydown和onkeyup 等之间的关系
- 搭建Openfire 开发环境
- QTP进阶过程
- HTTP 错误 500.21 - Internal Server Error
- 猫猫学IOS(三十七)UI之CALayer
- hdu 1166 敌兵布阵
- android升级到AppCompat v22.1.0后,onKeyDown 和 onKeyUp menu按键不能被触发的解决办法
- 对称加密算法之RC4介绍及OpenSSL中RC4常用函数使用举例
- 2.6 数据类型转换
- 解密jQuery事件核心 - 委托设计(二)
- 中国三大石油公司信息化进展
- C#中的流(一)
- ORA-12520: TNS:listener could not find available handler
- git 下 分支创建 合并 删除 相关操作
- Objective-C继承