use*_*702 6 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);
Run Code Online (Sandbox Code Playgroud)
创建片段后,一切运行正常,微调器位置设置为默认值,并且旋转器项目选择一次,如下面的日志所示:
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
Run Code Online (Sandbox Code Playgroud)
当我从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
Run Code Online (Sandbox Code Playgroud)
所以我有两个问题:
1)为什么微调器在从"返回"按钮返回时会注册2个项目选择.
2)是否有修复以防止发生2项选择?现在,片段正在填充重复数据,因为它会检索两次数据.
**编辑**更改为之后stateSpinner.setSelection(defaultState, false),我会得到一个空指针异常ballotsDisplay.removeAllViews();似乎ballotsDisplay由于某种原因设置为null
堆栈跟踪:
05-15 07:25:48.303 6153-6153/com.poliseewriters.polisee E/AndroidRuntime:FATAL EXCEPTION:com.polisee.ballotmeasures.BallotMeasuresFragment $ 1.onItemSelected(BallotMeasuresFragment.java:287)的主java.lang.NullPointerException在android .widget.AdapterView.fireOnSelected(AdapterView.java:882)位于android.widget.Adidget上的android.widget.AdapterView.selectionChanged(AdapterView.java:865)android.widget.Spinner.AdckterView.checkSelectionChanged(AdapterView.java:1017).布局(Spinner.java:363)位于android.widget.AbsSpinner.setSelectionInt(AbsSpinner.java:292)的android.widget.AbsSpinner.setSelection(AbsSpinner.java:269)at com.polisee.ballotmeasures.BallotMeasuresFragment.setStateSpinner(BallotMeasuresFragment) .java:314)在android.supporte.ball4.measures.BallotMeasuresFragment.onCreateView(BallotMeasuresFragment.java:201)的android.support.v4.app.Fragment.performCreateView(Fragment.java:1786)的android.support.v4.app. android.support上的FragmentManagerImpl.moveToState(FragmentManager.java:953).在android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java)的android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739)上的v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1136) 1499)在Android.os.Handler.dispatchMessage(Handler.java)的android.os.Handler.handleCallback(Handler.java:605)的android.support.v4.app.FragmentManagerImpl $ 1.run(FragmentManager.java:456) 92)在android.app.Looper.loop(Looper.java:137)的android.app.ActivityThread.main(ActivityThread.java:4441)java.lang.reflect.Method.invokeNative(Native Method)at java.lang位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java)的com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:784)中的.reflect.Method.invoke(Method.java:511) :551)at dalvik.system.NativeStart.main(Native Method)
**编辑:更新代码以防止onItemSelected执行两次,需要为ballotsDisplay添加null检查**
@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);
}
Run Code Online (Sandbox Code Playgroud)
用来stateSpinner.setSelection(defaultState, false);代替stateSpinner.setSelection(defaultState);
问题是onItemSelected()Android Framework会调用两次回调(可能是设计),第一次是view参数null,第二次是实例化.
您无法阻止2个项目选择发生,但您可以检查view变量是否为空,如果不是,则执行其他操作.