返回Fragment

时间:2015-05-15 06:49:55

标签: android android-fragments android-spinner

我为Fragment创建了一个微调器,用来自HTTP标注的数据填充它。首次创建Fragment时,我使用其选择选项填充微调器,设置其setOnItemSelectedListener并在onCreateView()中设置其初始选择。

    stateSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

        public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
        {


            if (spinnerPosition != position)
            {
                spinnerPosition = position;
                TextView stateSelected = (TextView) view;
                String stateSelectedStr = stateSelected.getText().toString();


                LinearLayout ballotsDisplay = (LinearLayout) getActivity().findViewById(R.id.ballotsDisplay);
                ballotsDisplay.removeAllViews();

                Map<String, String> calloutParams = new HashMap<String, String>();
                calloutParams.put("state", stateSelectedStr);

                // Create and execute AsyncTask to retrieve ballots
                new RetrieveBallots().execute(calloutParams);
            }
        }

        public void onNothingSelected(AdapterView<?> parent) {
            return;
        }
    });

    // Set default selection for spinner
    int defaultState = adapter.getPosition(userState);

    if (defaultState == -1)
    {
        defaultState = 0;
    }

    stateSpinner.setSelection(defaultState);

创建片段后,一切运作正常,微调器位置设置为默认值,并且旋转器项目选择一次,如下面的日志所示:

5009-5009/com.project.test D/TEST﹕ onCreateView called
5009-5009/com.project.test D/TEST﹕ stateSpinner.setSelection
5009-5009/com.project.test D/TEST﹕ onActivityCreated called
5009-5009/com.project.test D/TEST﹕ onResume called
5009-5009/com.project.test D/TEST﹕ spinner item selected

当我从Fragment导航到另一个片段(我将片段存储到backstack)时,会出现问题。当我单击返回以返回原始片段时,微调器似乎选择了两次项目:

5009-5009/com.project.test D/TEST﹕ onCreateView called
5009-5009/com.project.test D/TEST﹕ stateSpinner.setSelection
5009-5009/com.project.test D/TEST﹕ onActivityCreated called
5009-5009/com.project.test D/TEST﹕ onResume called
5009-5009/com.project.test D/TEST﹕ spinner item selected
5009-5009/com.project.test D/TEST﹕ spinner item selected

所以我有两个问题:

1)为什么微调器在从“返回”按钮返回时会注册2个项目选择。

2)是否有修复可以防止发生2项选择?现在,片段正在填充重复数据,因为它会检索两次数据。

**编辑** 更改为stateSpinner.setSelection(defaultState, false)后,我会在ballotsDisplay.removeAllViews();得到一个空指针异常,似乎因为某些原因将ballotsDisplay设置为null

stacktrace:

  

05-15 07:25:48.303 6153-6153 / com.poliseewriters.polisee E / AndroidRuntime:FATAL EXCEPTION:main       显示java.lang.NullPointerException               at com.polisee.ballotmeasures.BallotMeasuresFragment $ 1.onItemSelected(BallotMeasuresFragment.java:287)               在android.widget.AdapterView.fireOnSelected(AdapterView.java:882)               在android.widget.AdapterView.selectionChanged(AdapterView.java:865)               在android.widget.AdapterView.checkSelectionChanged(AdapterView.java:1017)               在android.widget.Spinner.layout(Spinner.java:363)               在android.widget.AbsSpinner.setSelectionInt(AbsSpinner.java:292)               在android.widget.AbsSpinner.setSelection(AbsSpinner.java:269)               在com.polisee.ballotmeasures.BallotMeasuresFragment.setStateSpinner(BallotMeasuresFragment.java:314)               在com.polisee.ballotmeasures.BallotMeasuresFragment.onCreateView(BallotMeasuresFragment.java:201)               在android.support.v4.app.Fragment.performCreateView(Fragment.java:1786)               在android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:953)               在android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1136)               在android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)               在android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1499)               在android.support.v4.app.FragmentManagerImpl $ 1.run(FragmentManager.java:456)               在android.os.Handler.handleCallback(Handler.java:605)               在android.os.Handler.dispatchMessage(Handler.java:92)               在android.os.Looper.loop(Looper.java:137)               在android.app.ActivityThread.main(ActivityThread.java:4441)               at java.lang.reflect.Method.invokeNative(Native Method)               在java.lang.reflect.Method.invoke(Method.java:511)               在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:784)               在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)               在dalvik.system.NativeStart.main(本地方法)

**编辑:更新代码以防止onItemSelected执行两次,需要为ballotsDisplay **添加空检查

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    if (savedInstanceState != null) {
        Log.d("TEST", "bundle = " + savedInstanceState.toString());
    }

    Log.d("TEST", "onCreateView called");

    View view = (View) inflater.inflate(R.layout.fragment_ballot_measures, container, false);

    setStateSpinner(view);

    return view;
}


private void setStateSpinner(View view) {

    try {
        states = Utilities.getAllStateNames();
    }
    catch (Exception e) {
        Log.e("Error", "Error retrieving names: " + e.getMessage());
    }

    Spinner stateSpinner = (Spinner) view.findViewById(R.id.stateSpinner);

    final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), R.layout.ballotmeasures_state_spinner, states);
    adapter.setDropDownViewResource(R.layout.ballotmeasures_state_spinner_dropdown);

    stateSpinner.setAdapter(adapter);

    stateSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

        // Callback method to invoke when a state has been selected
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
        {
            Log.d("TEST", "spinner item selected");

                TextView stateSelected = (TextView) view;
                String stateSelectedStr = stateSelected.getText().toString();

                // Remove all currently displayed views in the layout
                LinearLayout ballotsDisplay = (LinearLayout) getActivity().findViewById(R.id.ballotsDisplay);
                if (ballotsDisplay != null)
                {
                    ballotsDisplay.removeAllViews();
                }

                Map<String, String> calloutParams = new HashMap<String, String>();
                calloutParams.put("state", stateSelectedStr);

                // AsyncTask to execute data retrieval 
                new RetrieveBallots().execute(calloutParams);
            }

        public void onNothingSelected(AdapterView<?> parent) {
            return;
        }
    });

    // Set default selection for spinner
    int defaultState = adapter.getPosition(userState);

    if (defaultState == -1)
    {
        defaultState = 0;
    }

    Log.d("TEST", "stateSpinner.setSelection");
    stateSpinner.setSelection(defaultState, false);
}

3 个答案:

答案 0 :(得分:9)

使用stateSpinner.setSelection(defaultState, false);代替stateSpinner.setSelection(defaultState);

答案 1 :(得分:5)

问题是,onItemSelected()回调被Android框架调用两次(可能是设计),第一次view参数是null,第二次被实例化。

您无法阻止2个项目选择发生,但您可以检查view变量是否为空,如果不是,则执行其他操作。

答案 2 :(得分:0)

添加条件视图!=像这样在ItemSelectedListener中为空:

spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                    @Override
                    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                        if(view!=null)
                        {//write your code
                        }
                    }

                    @Override
                    public void onNothingSelected(AdapterView<?> parent) {

                    }
                });