实现v7 AppCompat后,Android搜索Widtget因NullPointerException而崩溃

时间:2014-03-28 01:14:04

标签: android search android-actionbar android-appcompat

我在实现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);

    }


}

0 个答案:

没有答案