delete from hateblo.jp where 1=1;

タイトルに意味はありません。

onCreateMenuのgetActionBarでNullPointerExceptionが発生する

対象

  • API version を 19→21へ更新した
  • SearchViewを使っている
    • ActionBarに虫眼鏡マークを出すアレ
  • SearchViewに渡す引数としてgetActivity().getActionBar().getThemedContext()とかしてる
    • getActivity().getActionBar()でnullになる

原因

なぜAPI19以前は正常に行っていたのか分けがわからないが、以下の理由によりNullPointerExceptionが発生していた。

  • onCreateOptionsMenu() は onCreate() の終盤で呼ばれる
  • setContentView() 以前に getActivity().getActionBar()を実行するとnullが返却される

問題のコード

public class IssueList extends ListFragment  {

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		FilterArgument intent = new FilterArgument();
		intent.setArgument( getArguments() );
		inflater.inflate( R.menu.refresh, menu );
		menu_refresh = menu.findItem(R.id.menu_refresh);

		setupSearchBar(menu);
		super.onCreateOptionsMenu(menu, inflater);
	}

	@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
	protected void setupSearchBar(Menu menu){
		if(! (getActivity() instanceof FragmentActivity)) {
			return;
		}
		ActionBar bar = ((FragmentActivity)getActivity()).getActionBar();
		//^^^^^^^^^^^^^^ NullPointerException
		SearchView search = new SearchView(bar.getThemedContext());
		search.setIconifiedByDefault(false);
		search.setSubmitButtonEnabled(true);
		search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
			//...snip...
		});
		menu.add(android.R.string.search_go)
				.setIcon(android.R.drawable.ic_menu_search)
				.setActionView(search)
				.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW)
		;
	}

}

修正

Activityのコンテキストでもテーマは適用されているので、そのまま使用することにする。
本来はonActivityCreated以降が望ましいが、なぜか正常に処理されるため、タイミングの修正は行わないこととする。

		//if(! (getActivity() instanceof FragmentActivity)) {
		//	return;
		//}

		//ActionBar bar = ((FragmentActivity)getActivity()).getActionBar();
		//^^^^^^^^^^^^^^ NullPointerException
		//SearchView search = new SearchView(bar.getThemedContext());
		SearchView search = new SearchView(getActivity());

参考文献