我在实现v7 AppCompat支持库后恢复应用程序时出现问题,现在:“... MainActivity.onCreateOptionsMenu(MainActivity.java:185)” - 总是返回NULL,我的应用程序崩溃。
我已经关注了最新的API Guide,并且已经重复了两次但是我无法修复它,到目前为止它几乎花了我一天...... :(
当我将“yourapp:actionViewClass =”android.support.v7.widget.SearchView“添加到我的搜索小部件菜单项时,我的应用程序将不再运行,所以我不知道多少次我再次阅读google文档...:(
请帮助我,我没有想法。 vedtam
logcat的:
03-28 00:59:00.195: W/dalvikvm(9375): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
03-28 00:59:00.205: E/AndroidRuntime(9375): FATAL EXCEPTION: main
03-28 00:59:00.205: E/AndroidRuntime(9375): java.lang.NullPointerException
03-28 00:59:00.205: E/AndroidRuntime(9375): at com.exploreca.tourfinder.MainActivity.onCreateOptionsMenu(MainActivity.java:185)
03-28 00:59:00.205: E/AndroidRuntime(9375): at android.app.Activity.onCreatePanelMenu(Activity.java:2490)
03-28 00:59:00.205: E/AndroidRuntime(9375): at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:407)
03-28 00:59:00.205: E/AndroidRuntime(9375): at com.android.internal.policy.impl.PhoneWindow.doInvalidatePanelMenu(PhoneWindow.java:769)
03-28 00:59:00.205: E/AndroidRuntime(9375): at com.android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.java:201)
03-28 00:59:00.205: E/AndroidRuntime(9375): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
03-28 00:59:00.205: E/AndroidRuntime(9375): at android.view.Choreographer.doCallbacks(Choreographer.java:562)
03-28 00:59:00.205: E/AndroidRuntime(9375): at android.view.Choreographer.doFrame(Choreographer.java:531)
03-28 00:59:00.205: E/AndroidRuntime(9375): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
03-28 00:59:00.205: E/AndroidRuntime(9375): at android.os.Handler.handleCallback(Handler.java:725)
03-28 00:59:00.205: E/AndroidRuntime(9375): at android.os.Handler.dispatchMessage(Handler.java:92)
03-28 00:59:00.205: E/AndroidRuntime(9375): at android.os.Looper.loop(Looper.java:137)
03-28 00:59:00.205: E/AndroidRuntime(9375): at android.app.ActivityThread.main(ActivityThread.java:5041)
03-28 00:59:00.205: E/AndroidRuntime(9375): at java.lang.reflect.Method.invokeNative(Native Method)
03-28 00:59:00.205: E/AndroidRuntime(9375): at java.lang.reflect.Method.invoke(Method.java:511)
03-28 00:59:00.205: E/AndroidRuntime(9375): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
03-28 00:59:00.205: E/AndroidRuntime(9375): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
03-28 00:59:00.205: E/AndroidRuntime(9375): at dalvik.system.NativeStart.main(Native Method)
03-28 01:04:00.395: I/Process(9375): Sending signal. PID: 9375 SIG: 9
main.xml中:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<!-- Search Widget -->
<item android:id="@+id/search"
android:icon="@drawable/ic_action_search"
android:title="@string/search_title"
android:showAsAction="always"
yourapp:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
searchable.xml:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/search_hint"
android:label="@string/app_name" />
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exploreca.tourfinder"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_exploreca"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.exploreca.tourfinder.MainActivity"
android:label="@string/app_name" >
<meta-data
android:name="android.app.default_searchable"
android:value=".SearchResultsActivity" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity">
</activity>
<activity
android:name=".TourDetailActivity">
</activity>
<!-- Search results activity -->
<activity android:name=".SearchActivity"
android:parentActivityName="com.exploreca.tourfinder.MainActivity" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
</application>
</manifest>
SearchActivity.java:
package com.exploreca.tourfinder;
import android.app.ActionBar;
import android.app.Activity;
import android.app.SearchManager;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class SearchActivity extends Activity {
private TextView txtQuery;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_results);
// get the action bar
ActionBar actionBar = getActionBar();
// Enabling Back navigation on Action Bar icon
actionBar.setDisplayHomeAsUpEnabled(true);
txtQuery = (TextView) findViewById(R.id.txtQuery);
handleIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
/**
* Handling intent data
*/
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
/**
* Use this query to display search results like
* 1. Getting the data from SQLite and showing in listview
* 2. Making webrequest and displaying the data
* For now we just display the query only
*/
txtQuery.setText("Search Query: " + query);
}
}
}
MainActivity:
package com.exploreca.tourfinder;
import java.util.List;
import android.app.ActionBar;
import android.app.ListActivity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
public class MainActivity extends ListActivity {
public static final String LOGTAG = "EXPLORECA";
public static final String USERNAME="pref_username";
public static final String VIEWIMAGE="pref_viewimages";
private SharedPreferences settings;
private OnSharedPreferenceChangeListener listener;
private List<Tour> tours;
//declaring Tours datasource
ToursDataSource datasource;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mPlanetTitles;
public String myArray[] = {"cluj", "satu", "etc"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar to show a dropdown list.
final ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
// Create an ArrayAdapter using the string array and a default spinner layout
// Create an ArrayAdapter using the string array and a default spinner layout
SpinnerAdapter mSpinnerAdapter = ArrayAdapter.createFromResource( actionBar.getThemedContext(),
R.array.music_categs, android.R.layout.simple_spinner_dropdown_item);
Spinner spinner = new Spinner(this);
// Specify the layout to use when the list of choices appears
// mSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(mSpinnerAdapter);
//Set the callback for the drop-down list with
actionBar.setListNavigationCallbacks(mSpinnerAdapter, null);
mTitle = mDrawerTitle = getTitle();
mPlanetTitles = getResources().getStringArray(R.array.planets_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
getActionBar().setTitle(mTitle);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActionBar().setTitle("Menu");
}
};
// Set the adapter for the list view
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mPlanetTitles));
// Set the list's click listener
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
settings = PreferenceManager.getDefaultSharedPreferences(this);
listener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
MainActivity.this.refreshDisplay();
}
};
settings.registerOnSharedPreferenceChangeListener(listener);
//instantieting the datasouce
datasource = new ToursDataSource(this);
datasource.open();
tours = datasource.findAll();
if (tours.size() == 0){
createData();
tours = datasource.findAll();
}
refreshDisplay();
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
//uj config a "menu" png-nek
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
// click listener for the listview menu items
private class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
selectItem(position);
}
}
// launching menus with the same position as in listview
private void selectItem(int position) {
if (position == 2){
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
}
// Highlight the selected item, update the title, and close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mPlanetTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
switch (item.getItemId()) {
case R.id.menu_all:
tours = datasource.findAll();
refreshDisplay();
break;
case R.id.menu_cheap:
tours = datasource.findFiltered("city=?", "Satu");
refreshDisplay();
break;
case R.id.menu_fancy:
//tours = datasource.findFiltered("price >= 1000", "city", "", "price DESC");
refreshDisplay();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
/* Called whenever we call invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content view
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
// menu.findItem(R.id.menu_all).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
protected void onResume(){
super.onResume();
datasource.open();
}
protected void onPause(){
super.onPause();
datasource.close();
}
private void createData() {
ToursPullParser parser = new ToursPullParser();
List<Tour> tours = parser.parseXML(this);
for(Tour tour : tours){
datasource.create(tour);
}
//inserting data into the table
/*
Tour tour = new Tour();
tour.setTitle("salton Sea, ohh");
tour.setDescription("Az ut a tohoz.");
tour.setPrice(990);
tour.setImage("salton_sea");
tour = datasource.create(tour);
Log.i(LOGTAG, "Tour created with id:" +tour.getId());
*/
}
public void refreshDisplay() {
ArrayAdapter <Tour> adapter = new TourListAdapter(this, tours);
setListAdapter(adapter);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Tour tour = tours.get(position);
Intent intent = new Intent(this, TourDetailActivity.class);
intent.putExtra(".Tour", tour);
startActivity(intent);
}
}