テーマとして、android:windowNoTitle="true"
を設定することで、ActionBar を表示させないようにすることができます。
こうすると、ActionBar を持たない Activity が出来上がるため、Activity#getActionBar()
やActivity#getSupportActionBar()
はnull
を返すようになります。
この場合、以下の点について気をつけていないと、見に覚えのないクラッシュログに苛まれることになります。
メニューキーを無効化する
メニューキーは、すなわち ActionItem の OverFlow の中身を呼び出す機能として使われます。
つまり、ActionBar の機能を使おうとします。
しかし、android:windowNoTitle="true"
なテーマの Activity では、ActionBar そのものが生成されないので、メニューキーのハンドリングをした時に NullPointerException となってしまいます。
例えば、以下の様なクラッシュレポートが来た場合、まさにこのような状況にあると言えます。
java.lang.NullPointerException
at android.support.v7.a.r.b(ActionBarImplICS.java:219)
at android.support.v7.a.r.(ActionBarImplICS.java:52)
at android.support.v7.a.r.(ActionBarImplICS.java:41)
at android.support.v7.a.l.a(ActionBarActivityDelegateICS.java:47)
at android.support.v7.a.g.b(ActionBarActivityDelegate.java:81)
at android.support.v7.a.f.getMenuInflater(ActionBarActivity.java:71)
at android.app.Activity.onCreatePanelMenu(Activity.java:2445)
at android.support.v4.app.q.onCreatePanelMenu(FragmentActivity.java:224)
at android.support.v7.a.f.a(ActionBarActivity.java:232)
at android.support.v7.a.l.a(ActionBarActivityDelegateICS.java:147)
at android.support.v7.a.f.onCreatePanelMenu(ActionBarActivity.java:199)
at android.support.v7.a.m.onCreatePanelMenu(ActionBarActivityDelegateICS.java:285)
at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:388)
at com.android.internal.policy.impl.PhoneWindow.onKeyDownPanel(PhoneWindow.java:779)
at com.android.internal.policy.impl.PhoneWindow.onKeyDown(PhoneWindow.java:1444)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1833)
at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3466)
at android.view.ViewRootImpl.handleFinishedEvent(ViewRootImpl.java:3439)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2577)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4475)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:559)
at dalvik.system.NativeStart.main(Native Method)
この回避策として、メニューキーを無効化する手段があります。
@Override // avoid inflating menu without action bar
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ( keyCode == KeyEvent.KEYCODE_MENU ) {
// do nothing
return true;
}
return super.onKeyDown(keyCode, event);
}
WebView の LongClick を無効化する
WebView は、デフォルトで長押しのイベントをハンドリングし、テキストの選択状態を取り扱うことが出来るようになります。
すると、テキストが選択状態になった時、Contextual ActionBar が有効になります。
つまり、ActionBar の機能を使おうとします。
しかし、前述のとおり ActionBar のインスタンスは無いので、またしても NullPointerException となります。
例えば、以下の様なクラッシュレポートが来た場合、まさにこのような状況にあると言えます。
java.lang.NullPointerException
at android.support.v7.a.r.b(ActionBarImplICS.java:219)
at android.support.v7.a.r.(ActionBarImplICS.java:52)
at android.support.v7.a.r.(ActionBarImplICS.java:41)
at android.support.v7.a.l.a(ActionBarActivityDelegateICS.java:47)
at android.support.v7.a.g.b(ActionBarActivityDelegate.java:81)
at android.support.v7.a.g.k(ActionBarActivityDelegate.java:205)
at android.support.v7.a.l.a(ActionBarActivityDelegateICS.java:196)
at android.support.v7.a.m.onActionModeStarted(ActionBarActivityDelegateICS.java:351)
at com.android.internal.policy.impl.PhoneWindow$DecorView.startActionMode(PhoneWindow.java:2255)
at com.android.internal.policy.impl.PhoneWindow$DecorView.startActionModeForChild(PhoneWindow.java:2178)
at android.view.ViewGroup.startActionModeForChild(ViewGroup.java:571)
at android.view.ViewGroup.startActionModeForChild(ViewGroup.java:571)
at android.view.ViewGroup.startActionModeForChild(ViewGroup.java:571)
at android.view.View.startActionMode(View.java:3607)
at android.webkit.WebView.setUpSelect(WebView.java:6103)
at android.webkit.WebView.selectText(WebView.java:4873)
at android.webkit.WebView.selectText(WebView.java:4866)
at android.webkit.WebView.performLongClick(WebView.java:4851)
at android.webkit.WebView$PrivateHandler.handleMessage(WebView.java:9422)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4475)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:559)
at dalvik.system.NativeStart.main(Native Method)
WebView の長押しを無効化するには、以下のようにします。
WebView webview = ...'
webview.setLongClickable(false);
webview.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
return true; // successfully handled.
}
});