-Update 23. August
Diese has been fixed wieder im v23.0.0 von appcompat-v7 Support-Bibliothek. Aktualisieren Sie auf die letzte Version, um dies zu beheben.
-Update 19. Juli
Leider brach AppCompat v22.2.1 die onKeyDown
und onKeyUp
Ereignisse again. Ich habe gerade AppCompatActivityMenuKeyInterceptor
aktualisiert v22.1.x zu unterstützen und auch v22.2.1
-Update 29. Mai
Diese has been fixed im v22.2.0 von appcompat-v7 Support-Bibliothek. Aktualisieren Sie auf die letzte Version, um dies zu beheben.
Leider AppCompat v22.1.0 fängt die onKeyDown
und onKeyUp
Ereignisse und sie nicht propagieren, wenn die Menütaste gedrückt wird. Die einzige mögliche Lösung besteht darin, Reflection zu verwenden, um die Ereignisse onKeyDown
und onKeyUp
abzufangen, bevor die AppCompat tut.
Fügen Sie diese Klasse zu einem Projekt:
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);
Class mDelegateClass = mDelegate.getClass().getSuperclass();
Field mWindowField = null;
while (mDelegateClass != null) {
try {
mWindowField = mDelegateClass.getDeclaredField(FIELD_NAME_WINDOW);
break;
} catch (NoSuchFieldException ignored) {
}
mDelegateClass = mDelegateClass.getSuperclass();
}
if (mWindowField == null)
throw new NoSuchFieldException(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();
AppCompatActivity appCompatActivity = mActivityWeak.get();
if (appCompatActivity != null && keyCode == KeyEvent.KEYCODE_MENU) {
if (appCompatActivity.dispatchKeyEvent(event))
return true;
}
return super.dispatchKeyEvent(event);
}
}
}
Anruf AppCompatActivityMenuKeyInterceptor.intercept(this)
im onCreate
Ihrer Aktivität:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initialize the interceptor
AppCompatActivityMenuKeyInterceptor.intercept(this);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Now onKeyDown is called also for KEYCODE_MENU
if (keyCode == KeyEvent.KEYCODE_MENU) {
//do your stuff
//return false if you want to propagate the
//KeyEvent to AppCompat, return true otherwise
return false;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// Now onKeyUp is called also for KEYCODE_MENU
if (keyCode == KeyEvent.KEYCODE_MENU) {
//do your stuff
//return false if you want to propagate the
//KeyEvent to AppCompat, return true otherwise
return false;
}
return super.onKeyUp(keyCode, event);
}
}
Wenn Sie ProGuard verwenden oder DexGuard diese Regeln zu Ihrer Konfiguration hinzuzufügen:
-keepclassmembers class android.support.v7.app.AppCompatActivity {
private android.support.v7.app.AppCompatDelegate mDelegate;
}
-keepclassmembers class android.support.v7.app.AppCompatDelegateImplBase {
final android.view.Window mWindow;
}
Jetzt kann Ihre Aktivitätempfangenund onKeyUp
Ereignis auch für die Menütaste.
Antwort auf Ihre eigene Frage? Im selben Moment? – Niels
Ja, ich folgte dem Ratschlag von diesem [Artikel] (http://stackoverflow.com/help/self-answer) in der Hilfe von Stack Overflow –
Es scheint onKeyDown und onKeyUp Ereignisse werden jetzt korrekt für Menüschlüssel auf AppCompat ausgelöst v22.2.0. – NullNoname