Android 查看 iflation 异常

Android View iflation exception

我因以下错误而强制关闭:

android.view.InflateException: Couldn't resolve menu item onClick handler scanBarcode in class com.beerportfolio.beerportfoliopro.MainDrawer2
       at android.view.MenuInflater$InflatedOnMenuItemClickListener.<init>(MenuInflater.java)
       at android.view.MenuInflater$MenuState.setItem(MenuInflater.java)
       at android.view.MenuInflater$MenuState.addItem(MenuInflater.java)
       at android.view.MenuInflater.parseMenu(MenuInflater.java)
       at android.view.MenuInflater.inflate(MenuInflater.java)
       at com.beerportfolio.beerportfoliopro.MainDrawer2.onCreateOptionsMenu(MainDrawer2.java:172)
       at android.app.Activity.onCreatePanelMenu(Activity.java)
       at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:224)
       at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java)
       at com.android.internal.policy.impl.PhoneWindow.doInvalidatePanelMenu(PhoneWindow.java)
       at com.android.internal.policy.impl.PhoneWindow.run(PhoneWindow.java)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java)
       at android.view.Choreographer.doCallbacks(Choreographer.java)
       at android.view.Choreographer.doFrame(Choreographer.java)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java)
       at android.os.Handler.handleCallback(Handler.java)
       at android.os.Handler.dispatchMessage(Handler.java)
       at android.os.Looper.loop(Looper.java)
       at android.app.ActivityThread.main(ActivityThread.java)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
       at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: java.lang.NoSuchMethodException: scanBarcode [interface android.view.MenuItem]
       at java.lang.Class.getConstructorOrMethod(Class.java)
       at java.lang.Class.getMethod(Class.java)
       at android.view.MenuInflater$InflatedOnMenuItemClickListener.<init>(MenuInflater.java)
       at android.view.MenuInflater$MenuState.setItem(MenuInflater.java)
       at android.view.MenuInflater$MenuState.addItem(MenuInflater.java)
       at android.view.MenuInflater.parseMenu(MenuInflater.java)
       at android.view.MenuInflater.inflate(MenuInflater.java)
       at com.beerportfolio.beerportfoliopro.MainDrawer2.onCreateOptionsMenu(MainDrawer2.java:172)
       at android.app.Activity.onCreatePanelMenu(Activity.java)
       at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:224)
       at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java)
       at com.android.internal.policy.impl.PhoneWindow.doInvalidatePanelMenu(PhoneWindow.java)
       at com.android.internal.policy.impl.PhoneWindow.run(PhoneWindow.java)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java)
       at android.view.Choreographer.doCallbacks(Choreographer.java)
       at android.view.Choreographer.doFrame(Choreographer.java)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java)
       at android.os.Handler.handleCallback(Handler.java)
       at android.os.Handler.dispatchMessage(Handler.java)
       at android.os.Looper.loop(Looper.java)
       at android.app.ActivityThread.main(ActivityThread.java)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
       at dalvik.system.NativeStart.main(NativeStart.java)

我的 maindrawer2 文件看起来像这样:

public class MainDrawer2 extends FragmentActivity
{
    private static final String EXTRA_NAV_ITEM    = "extraNavItem";
    private static final String STATE_CURRENT_NAV = "stateCurrentNav";

    private ActionBarDrawerToggle mDrawerToggle;
    private DrawerLayout mDrawerLayout;


    private NavDrawerListAdapter mDrawerAdapter;
    private ListView mDrawerList;

    private CharSequence mTitle;
    private CharSequence mDrawerTitle;

    private MainNavItem mCurrentNavItem;


    public static Intent createLaunchFragmentIntent(Context context, MainNavItem navItem)
    {
        return new Intent(context, MainDrawer2.class)
                .putExtra(EXTRA_NAV_ITEM, navItem.ordinal());
    }



    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_main);

        Crashlytics.start(this);



        mTitle = mDrawerTitle = getTitle();
        mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
        mDrawerList   = (ListView)findViewById(R.id.drawer);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        enableHomeButtonIfRequired();

        mDrawerAdapter = new NavDrawerListAdapter(getApplicationContext());
        mDrawerList.setAdapter(mDrawerAdapter);
        mDrawerList.setOnItemClickListener(new ListView.OnItemClickListener()
        {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id)
            {
                displayNavFragment((MainNavItem)parent.getItemAtPosition(position));
            }
        });

        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer, R.string.app_name, R.string.app_name)
        {
            public void onDrawerClosed(View view)
            {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView)
            {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu();
            }
        };

        mDrawerLayout.setDrawerListener(mDrawerToggle);

        if(getIntent().hasExtra(EXTRA_NAV_ITEM)){
            MainNavItem navItem = MainNavItem.values()
                    [getIntent().getIntExtra(EXTRA_NAV_ITEM,
                    MainNavItem.STATISTICS.ordinal())];
            displayNavFragment(navItem);
        }
        else if(savedInstanceState != null){
            mCurrentNavItem = MainNavItem.values()
                    [savedInstanceState.getInt(STATE_CURRENT_NAV)];
            setCurrentNavItem(mCurrentNavItem);
        }
        else{
            displayNavFragment(MainNavItem.STATISTICS);
        }
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    private void enableHomeButtonIfRequired()
    {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){
            getActionBar().setHomeButtonEnabled(true);
        }
    }
    public void setActionBarTitle(String title) {
        getActionBar().setTitle(title);
    }


    @Override
    public void setTitle(CharSequence title)
    {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState)
    {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        // Pass any configuration change to the drawer toggles
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);

        if (mCurrentNavItem == null){


        }
        else{
            outState.putInt(STATE_CURRENT_NAV, mCurrentNavItem.ordinal());
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    /*
    @Override
    public boolean onPrepareOptionsMenu(Menu menu)
    {
        // if nav drawer is opened, hide the action items
        boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
        menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }
    */



    private void displayNavFragment(MainNavItem navItem)
    {
        //if(navItem == mCurrentNavItem){
        //  return;
        //}
        Fragment fragment = Fragment.instantiate(this,
                navItem.getFragClass().getName());
        if(fragment != null){

            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.main, fragment)
                    .commit();
            setCurrentNavItem(navItem);
        }
    }

    private void setCurrentNavItem(MainNavItem navItem)
    {
        int position = navItem.ordinal();
        // If navItem is in DrawerAdapter
        if(position >= 0 && position < mDrawerAdapter.getCount()){
            //mDrawerList.setItemChecked(position, true);
        }
        else{
            // navItem not in DrawerAdapter, de-select current item
            if(mCurrentNavItem != null){
                //mDrawerList.setItemChecked(mCurrentNavItem.ordinal(), false);
            }
        }

        //test to keep item not selected
        int toClear=mDrawerList.getCheckedItemPosition();

        if (toClear >= 0) {
            mDrawerList.setItemChecked(toClear, false);
        }

        mDrawerLayout.closeDrawer(mDrawerList);
        setTitle(navItem.getTitleResId());
        mCurrentNavItem = navItem;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                if(mDrawerLayout.isDrawerOpen(mDrawerList)) {
                    mDrawerLayout.closeDrawer(mDrawerList);
                }
                else {
                    mDrawerLayout.openDrawer(mDrawerList);
                }
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }




    public void goToSearch(MenuItem item){

        //go to search page
        Fragment Fragment_one;
        FragmentManager man= getSupportFragmentManager();
        FragmentTransaction tran = man.beginTransaction();
        Fragment_one = new Search();

        tran.replace(R.id.main, Fragment_one);//tran.
        tran.addToBackStack(null);
        tran.commit();

    }

    public void scanBarcode(MenuItem item){

        //open scanner
        IntentIntegrator scanIntegrator = new IntentIntegrator(this);
        scanIntegrator.initiateScan();



    }

    public void onActivityResult(int requestCode, int resultCode, Intent intent) {

        //retrieve scan result
        IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
        if (scanningResult != null) {
            //we have a result

            String scanContent = scanningResult.getContents();

            //todo: set scan content into setting, load new fragment which calls async task below. New
            //todo: fragment will have same ui as search. :-)
            Fragment Fragment_one;




            FragmentManager man= this.getSupportFragmentManager();
            FragmentTransaction tran = man.beginTransaction();
            BarcodeFrag fragmentNew = new BarcodeFrag();
            Bundle bundle = new Bundle();
            bundle.putString("scanContent", scanContent);
            fragmentNew.setArguments(bundle);


            tran.replace(R.id.main, fragmentNew);//tran.
            tran.addToBackStack(null);
            //tran.commit();
            tran.commitAllowingStateLoss();


        }

        else{
            Toast toast = Toast.makeText(getApplicationContext(),
                    "No scan data received!", Toast.LENGTH_SHORT);
            toast.show();
        }

    }



}

main.xml 是:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/action_statisticsHome"
        android:orderInCategory="100"
        android:showAsAction="never"
        android:onClick="goToStatistics"
        android:title="Your Statistics"/>

    <item android:id="@+id/menu_search2"
          android:title="Test"
          android:icon="@android:drawable/ic_menu_search"
          android:showAsAction="ifRoom|collapseActionView"
          android:actionViewClass="android.widget.SearchView" />


</menu>

res/menu/main.xml中,您必须在菜单项上严格指定:

android:onClick="scanBarcode"

注意空格或 @string/* 引用

Activity 中的 public void scanBarcode(MenuItem item) 是对菜单项的引用, 必须 在关联的 menu.xml[=24= 中]

编辑(自 main.xml):
我在您的代码中发现了一些可能导致您的应用程序崩溃的问题

  • 在你的 main.xml 中你有一个 android:onClick="goToStatistics"。 此属性告诉 MenuInflater 您的 activity 有一个 public void goToStatistics(MenuItem item) 方法,但它没有。
  • 您的 Activity 有两个方法可由某些菜单项触发,但在您的 main.xml 中没有任何菜单项与这些方法关联:
    • public void goToSearch(MenuItem item)
    • public void scanBarcode(MenuItem item)