返回到Fragment时,Android Spinner的onItemSelected执行了两次 [英] Android Spinner's onItemSelected executed twice when going back to Fragment

查看:97
本文介绍了返回到Fragment时,Android Spinner的onItemSelected执行了两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I created a spinner for my Fragment that populates it with data retrieved from an HTTP callout. When the Fragment is first created, I populate the spinner with its selection choices, set its setOnItemSelectedListener and set its initial selection in 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);

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

When the Fragment is created, everything works well, the spinner position is set to its default and the spinner item is selected once as shown in the log below:

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

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

The problem occurs when I navigate away from the Fragment to another fragment (I store the fragment onto backstack). When I click back to go back to my original Fragment, the spinner seems to have its item selected twice:

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

所以我有2个问题:

1)为什么微调器在从后退"按钮返回时登记了2个项目选择.

1) Why does the spinner register 2 item selection occurrences when returning to it from the Back button.

2)是否有修复程序可以防止选择2个项目?现在,该片段正在填充重复数据,因为它两次检索了数据.

2) Is there a fix to prevent 2 item selections from occurring? Right now the fragment is being populated with duplicate data since it retrieves the data twice.

**编辑** 更改为stateSpinner.setSelection(defaultState, false)后,我会在ballotsDisplay.removeAllViews();处得到一个空指针异常,好像由于某种原因,ballotsDisplay设置为null

** EDIT ** After changing to stateSpinner.setSelection(defaultState, false), I would get a null Pointer exception at ballotsDisplay.removeAllViews(); seems like ballotsDisplay is set to null for some reason with that change

stacktrace:

stacktrace:

05-15 07:25:48.303 6153-6153/com.poliseewriters.polisee E/AndroidRuntime:致命异常:主要 java.lang.NullPointerException 在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) 在java.lang.reflect.Method.invokeNative(本机方法) 在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(本机方法)

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) at android.widget.AdapterView.fireOnSelected(AdapterView.java:882) at android.widget.AdapterView.selectionChanged(AdapterView.java:865) at android.widget.AdapterView.checkSelectionChanged(AdapterView.java:1017) at android.widget.Spinner.layout(Spinner.java:363) at android.widget.AbsSpinner.setSelectionInt(AbsSpinner.java:292) at android.widget.AbsSpinner.setSelection(AbsSpinner.java:269) at com.polisee.ballotmeasures.BallotMeasuresFragment.setStateSpinner(BallotMeasuresFragment.java:314) at com.polisee.ballotmeasures.BallotMeasuresFragment.onCreateView(BallotMeasuresFragment.java:201) at android.support.v4.app.Fragment.performCreateView(Fragment.java:1786) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:953) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1136) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1499) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:456) at android.os.Handler.handleCallback(Handler.java:605) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4441) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(Native Method)

**更新了代码以防止onItemSelected执行两次,需要添加对ballotsDisplay的空检查**

** Updated code to prevent onItemSelected from executing twice, needed to add null check for 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);
}

推荐答案

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

这篇关于返回到Fragment时,Android Spinner的onItemSelected执行了两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆