[ActionBar]無標題欄時點擊菜單鍵出現空指針的解決辦法.

1.當Activity繼承ActionBarActivity時,若無標題欄,則會出現空指針異常:


<item name="android:windowNoTitle">true</item>


04-13 18:36:27.984: E/AndroidRuntime(1969): FATAL EXCEPTION: main
04-13 18:36:27.984: E/AndroidRuntime(1969): java.lang.NullPointerException
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.support.v7.app.ActionBarImplICS.getThemedContext(ActionBarImplICS.java:287)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.support.v7.app.ActionBarImplJB.getThemedContext(ActionBarImplJB.java:20)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.support.v7.app.ActionBarActivityDelegate.getMenuInflater(ActionBarActivityDelegate.java:98)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.support.v7.app.ActionBarActivity.getMenuInflater(ActionBarActivity.java:71)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at com.fanhl.flingover.MainActivity.onCreateOptionsMenu(MainActivity.java:108)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.app.Activity.onCreatePanelMenu(Activity.java:2551)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:224)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.support.v7.app.ActionBarActivity.superOnCreatePanelMenu(ActionBarActivity.java:232)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.support.v7.app.ActionBarActivityDelegateICS.onCreatePanelMenu(ActionBarActivityDelegateICS.java:147)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.support.v7.app.ActionBarActivity.onCreatePanelMenu(ActionBarActivity.java:199)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.onCreatePanelMenu(ActionBarActivityDelegateICS.java:285)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:465)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at com.android.internal.policy.impl.PhoneWindow.onKeyDownPanel(PhoneWindow.java:853)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at com.android.internal.policy.impl.PhoneWindow.onKeyDown(PhoneWindow.java:1523)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1921)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3659)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.view.ViewRootImpl.handleImeFinishedEvent(ViewRootImpl.java:3629)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:2870)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.os.Handler.dispatchMessage(Handler.java:99)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.os.Looper.loop(Looper.java:137)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at android.app.ActivityThread.main(ActivityThread.java:4881)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at java.lang.reflect.Method.invokeNative(Native Method)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at java.lang.reflect.Method.invoke(Method.java:511)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:804)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:571)
04-13 18:36:27.984: E/AndroidRuntime(1969): 	at dalvik.system.NativeStart.main(Native Method)



2.解決辦法是.

2.1:禁止點擊菜單鍵


	/**
	 * 禁止點擊菜單鍵
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_MENU) {
			// do nothing
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

2.2:不禁用標題欄

URL: How to hide action bar before activity is created, and then show it again?


Setting android:windowActionBar=false truly disables the ActionBar but then, as you say, getActionBar() returns null. This is solved by:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
    getActionBar().hide();

    setContentView(R.layout.splash); // be sure you call this AFTER requestFeature

This creates the ActionBar and immediately hides it before it had the chance to be displayed.

But now there is another problem. After putting windowActionBar=false in the theme, the Activity draws its normal Window Title instead of an ActionBar.
If we try to avoid this by using some of the *.NoTitleBar stock themes or we try to put <item name="android:windowNoTitle">true</item> in our own theme, it won't work.
The reason is that the ActionBar depends on the Window Title to display itself - that is the ActionBar is a transformed Window Title.
So the trick which can help us out is to add one more thing to our Activity theme xml:

<item name="android:windowActionBar">false</item>
<item name="android:windowTitleSize">0dp</item>

This will make the Window Title with zero height, thus practically invisible .

In your case, after you are done with displaying the splash screen you can simply call

setContentView(R.layout.main);
getActionBar().show()

and you are done. The Activity will start with no ActionBar flickering, nor Window Title showing.

ADDON: If you show and hide the ActionBar multiple times maybe you have noticed that the first showing is not animated. From then on showing and hiding are animated. If you want to have animation on the first showing too you can use this:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_ACTION_BAR);

    // delaying the hiding of the ActionBar
    Handler h = new Handler();
    h.post(new Runnable() {     
        @Override
        public void run() {
            getActionBar().hide();
        }
    });

The same thing can be achieved with:

protected void onPostResume() {
    super.onPostResume();
    getActionBar().hide();

but it may need some extra logic to check if this is the first showing of the Activity.

The idea is to delay a little the hiding of the ActionBar. In a way we let the ActionBar be shown, but then hide it immediately. Thus we go beyond the first non-animated showing and next showing will be considered second, thus it will be animated.

As you may have guessed there is a chance that the ActionBar could be seen before it has been hidden by the delayed operation. This is actually the case. Most of the time nothing is seen but yet, once in a while, you can see the ActionBar flicker for a split second.

In any case this is not a pretty solution, so I welcome any suggestions.



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章