spinner.setAdapter(适配器)导致"资源是在附加的堆栈跟踪中获取但从未发布的#34;错误和app力量关闭

时间:2015-06-21 19:46:48

标签: java android nullpointerexception

我正在尝试使用ArrrayAdapter更改微调器中的项目,使用spinner.setAdapter(适配器)

当选择侧边栏项目时,此代码会运行,更改微调器中的值

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        String Tag = "Navigation drawer";
        Log.v(Tag, "Drawer item toggled");

        Spinner spinner = (Spinner) getView().findViewById(R.id.inputSpinner);
        //Get view must be used in order to use findViewById inside a fragment
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getActivity().getApplicationContext(), //getActivity gets the correct context for me
                R.array.area_units_array, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); //Tells the adapter what layout to use
        spinner.setAdapter(adapter);

        return true;
    }

    return super.onOptionsItemSelected(item);
}

引发的错误如下

06-21 19:44:09.688    4715-4715/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.anapp.tpb.sidebarproject, PID: 4715
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Spinner.setAdapter(android.widget.SpinnerAdapter)' on a null object reference
        at com.anapp.tpb.sidebarproject.NavigationDrawerFragment.onOptionsItemSelected(NavigationDrawerFragment.java:272)
        at android.app.Fragment.performOptionsItemSelected(Fragment.java:2159)
        at android.app.FragmentManagerImpl.dispatchOptionsItemSelected(FragmentManager.java:1988)
        at android.app.Activity.onMenuItemSelected(Activity.java:2888)
        at com.android.internal.widget.ToolbarWidgetWrapper$1.onClick(ToolbarWidgetWrapper.java:182)
        at android.view.View.performClick(View.java:4780)
        at android.view.View$PerformClick.run(View.java:19866)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5257)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
--------- beginning of system

我已经通过这个NullPointer异常阅读了其他人,我可以看到它来自Spinner spinner = (Spinner) getView().findViewById(R.id.inputSpinner); 行,但我不知道为什么。微调器输入微调器&#39;存在。

如果对这个问题有明显的答案我很抱歉。我刚刚完成了我的GCSE,在此之前我只使用过Python。 Java对我来说相对较新,所以我正在制作一个简单的单位转换器应用程序。

2 个答案:

答案 0 :(得分:1)

尝试更改j

Spinner spinner = (Spinner) getView().findViewById(R.id.inputSpinner);

因为您使用Spinner spinner = (Spinner) findViewById(R.id.inputSpinner);将其转换为Spinner视图并且知道ViewID,所以无需调用(Spinner)然后使用该ID。

不确定是否能解决问题。

此外,仅使用getView(),再次,无需从活动中获取应用程序上下文。单独使用getApplicationContext()(或getActivity())。

PS:Google Docs令人惊叹!使用它们!

答案 1 :(得分:0)

最后,我使用MainActivity中的public void onNavigationDrawerItemSelected(int position) {修复了问题,该活动在所选项目上运行。 我修改它以获取位置参数,然后将ArrayAdapter代码放入其中,使用if语句根据所选的导航抽屉项加载不同的数组。 但是,我无法更新此代码中的微调器,因此使用了一种方法来更新微调器。 ķpublic void setAdapter(ArrayAdapter items){ Spinner inputSpinner = (Spinner) findViewById(R.id.inputSpinner); Spinner outputSpinner = (Spinner) findViewById(R.id.outputSpinner); inputSpinner.setAdapter(items); outputSpinner.setAdapter(items); String Tag = "setAdapter function"; Log.v(Tag, "Function has been called"); }

我遇到的下一个问题是,在打开应用程序时,会调用onNavigationDrawerItemSelected方法。这导致了一个强制关闭问题,因为该方法试图将项目添加到尚未存在的微调器中。 为了解决这个问题,我创建了一个变量来计算运行onNavigationDrawerItemSelected方法的次数,并添加了一个if语句,以便只有在此值大于0时才更新微调器

    public int drawerCount = 0;
@Override
public void onNavigationDrawerItemSelected(int position) {

    // update the main content by replacing fragments
    Spinner inputSpinner = (Spinner) findViewById(R.id.inputSpinner);
    Spinner outputSpinner = (Spinner) findViewById(R.id.outputSpinner);
    //Get view must be used in order to use findViewById inside a fragment
    if (position == 1) {
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, //getActivity gets the correct context for me
                R.array.area_units_array, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); //Tells the adapter what layout to use
        setAdapter(adapter);
        String Tag = "Spinner update";
        Log.v(Tag, "Position 0 has been selected");
    } else if(position == 2){
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, //getActivity gets the correct context for me
                R.array.data_units_array, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); //Tells the adapter what layout to use
        setAdapter(adapter);
        String Tag = "Spinner update";
        Log.v(Tag, "Position 2 has been selected");

    } else if(position == 3){
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, //getActivity gets the correct context for me
                R.array.density_units_array, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); //Tells the adapter what layout to use
        setAdapter(adapter);
        String Tag = "Spinner update";
        Log.v(Tag, "Position 3 has been selected");
        //The elif below runs only once the drawer has been opened once or more. It stops the app closing on startup
    } else if(drawerCount > 0){ //This must be at the bottom or it mucks with the elifs below
        //The line below checks if the change is actually needed, if the drawer item selected is Angle
        if(position == 0){
            ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, //getActivity gets the correct context for me
                    R.array.angle_units_array, android.R.layout.simple_spinner_item);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); //Tells the adapter what layout to use
            setAdapter(adapter);
            String Tag = "Spinner update";
            Log.v(Tag, "Position 0 has been selected");
        }

    }
    drawerCount++;
    String Tag = "Spinner update";
    Log.v(Tag, "The drawerCount has been incremented it is equal to " + drawerCount);
    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction()
            .replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
            .commit();


} //The function below is used to change the values in the two spinners.
//Doing this within the onNavigationDrawerItemSelected function caused a force close
public void setAdapter(ArrayAdapter items){
    Spinner inputSpinner = (Spinner) findViewById(R.id.inputSpinner);
    Spinner outputSpinner = (Spinner) findViewById(R.id.outputSpinner);
    inputSpinner.setAdapter(items);
    outputSpinner.setAdapter(items);
    String Tag = "setAdapter function";
    Log.v(Tag, "Function has been called");
}

不可否认,代码有点乱,但它工作正常并且速度不是很慢,因此不需要立即修复。