Android 如何使用OnsavedInstance保存微调器及其适配器,并在保存后进行恢复?
我在应用程序中处理两个微调器的onSavedInstance和onRestoreInstance时遇到问题 我有两个SpinnerAdapter,可以用一对ArrayAdapter动态填充-adapter1/adapter2和adapter3/adapter4 在onCreate method应用程序中,为它们创建4个适配器,当用户按下按钮1时,它会用适配器1和适配器2填充喷丝头From和喷丝头To,当按钮2分别用适配器3和适配器4填充喷丝头 正如我所理解的生命周期——当屏幕旋转时,android会破坏应用程序,然后从一开始就恢复它 所以在onSavedInstancei我把我的纺纱机放进一捆Android 如何使用OnsavedInstance保存微调器及其适配器,并在保存后进行恢复?,android,android-arrayadapter,android-spinner,onsaveinstancestate,Android,Android Arrayadapter,Android Spinner,Onsaveinstancestate,我在应用程序中处理两个微调器的onSavedInstance和onRestoreInstance时遇到问题 我有两个SpinnerAdapter,可以用一对ArrayAdapter动态填充-adapter1/adapter2和adapter3/adapter4 在onCreate method应用程序中,为它们创建4个适配器,当用户按下按钮1时,它会用适配器1和适配器2填充喷丝头From和喷丝头To,当按钮2分别用适配器3和适配器4填充喷丝头 正如我所理解的生命周期——当屏幕旋转时,androi
savedInstanceState.putInt("from",spinnerFrom.getSelectedItemPosition);
savedInstanceState.putInt("to",spinnertTo.getSelectedItemPosition());
在恢复时,我从bundle中检索它们:
spinnerFrom.setSelection(savedInstanceState.getInt("from"));
spinnertTo.setSelection(savedInstanceState.getInt("to"));
问题是:当应用程序还原时,它会丢失我的适配器,它们会得到空值
为了检查它,我创建了技术按钮和下一个代码:
protected void checkAdapter () {
//get Adapter from spinners
SpinnerAdapter valueAdapter = spinnerFrom.getAdapter();
SpinnerAdapter resultAdapter = spinnertTo.getAdapter();
if (valueAdapter == null | resultAdapter== null) {
Toast.makeText(this, “adapter null” , Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(this, “adapters not null” , Toast.LENGTH_SHORT).show();
}
}
// here i saving arraylist that ussualy i get from resources.
savedInstanceState.putStringArray(ADAPTER_TO,getStringArray(spinnerFrom.getAdapter()));
savedInstanceState.putStringArray(ADAPTER_FROM,getStringArray(spinnerFrom.getAdapter()));
问题:如何正确地将AdroidSpinner及其适配器放入OnSavedInstance捆绑包中,然后在RestoreInstance上恢复它,以防它不是在onCreate中而是在onClick方法中填充?
提前谢谢
应用程序java代码:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import android.widget.Toast;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends AppCompatActivity {
protected double getEnteredValue;
protected SpinnerAdapter checkAdapter;
protected int pos;
protected ArrayAdapter<String> adapter 1, adapter2, adapter3,
adapter4;
//butterknife bindings
@BindView(R.id.unit_From_spinner)Spinner spinnerFrom;
@BindView(R.id.unit_To_spinner)Spinner spinnertTo;
@BindView(R.id.radio_result_group) RadioGroup resultGroup;
@BindView(R.id.radio_value_gropu) RadioGroup valueGroup;
@BindView(R.id.valueEditTextView) EditText valueEdit;
@BindView(R.id.resultView) TextView resultView;
@BindView(R.id.conver_button) Button convertButton;
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString("result",resultView.getText().toString()); savedInstanceState.putString("value",valueEdit.getText().toString()); savedInstanceState.putInt("from",spinnerFrom.getSelectedItemPosition);
savedInstanceState.putInt("to",spinnertTo.getSelectedItemPosition());
savedInstanceState.putInt("radGroup1",resultGroup.getCheckedRadioButtonId());
savedInstanceState.putInt("radGroup2", valueGroup.getCheckedRadioButtonId());
super.onSaveInstanceState(savedInstanceState);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.unifiedlayout);
ButterKnife.bind(this);
//adapters for spinners
adapter1 = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_spinner_item,getResources().getStringArray( R.array.adapter_1) );
adapter2 = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_spinner_item,getResources().getStringArray(R.array. adapter_2));
adapter3 = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_spinner_item,getResources().getStringArray( R.array. adapter_3) );
adapter4 = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_spinner_item,getResources().getStringArray(R.array. adapter_4));}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
resultView.setText(savedInstanceState.getString("result"));
valueEdit.setText(savedInstanceState.getString("value"));
spinnerFrom.setSelection(savedInstanceState.getInt("from"));
spinnertTo.setSelection(savedInstanceState.getInt("to"));
super.onSaveInstanceState(savedInstanceState);
}
//OnClick
@OnClick({R.id.button1, R.id.button2,R.id.button3,R.id.button4} )
public void setViewOnClickEvent(View view){
switch(view.getId()){
case R.id. button1:
fillSpinner(adapter1, adapter2); // fill spinner with values
break;
case R.id. button2:
fillSpinner(adapter3,
adapter4);
break;
//button for check if any adapter active
case R.id.buttonAdapter:
checkAdapter () ;
break;
}
}
//fill spinners when user checks radiobutton in radiogroups
protected void fillSpinner (final ArrayAdapter<String> spinnerToAdapter,
final ArrayAdapter<String> spinnerFromAdapter){
valueGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup valueGroup, int checkedId) {
pos = valueGroup.indexOfChild(findViewById(checkedId));
switch (pos) {
case 0:
spinnerFrom.setAdapter(spinnerToAdapter);
break;
case 1:
spinnerFrom.setAdapter(spinnerFromAdapter);
break;
}
}
});
resultGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup resultGroup, int checkedId) {
pos = resultGroup.indexOfChild(findViewById(checkedId));
switch (pos) {
case 0:
spinnertTo.setAdapter(spinnerToAdapter);
break;
case 1:
spinnertTo.setAdapter(spinnerFromAdapter);
break;
}
}
});
}
//simple method for check if both spinners has null value
protected void checkAdapter () {
//get Adapter from spinners
SpinnerAdapter valueAdapter = spinnerFrom.getAdapter();
SpinnerAdapter resultAdapter = spinnertTo.getAdapter();
if (valueAdapter == null | resultAdapter== null) {
Toast.makeText(this, “adapter null” , Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(this, “adapters not null” , Toast.LENGTH_SHORT).show();
}
}
3.在restoreInstance中,创建新适配器,用值填充微调器,并使用savedInstanceState.getStringArrayADAPTER_填充保存的值:
toAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_spinner_item, savedInstanceState.getStringArray(ADAPTER_TO));
fromAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_spinner_item, savedInstanceState.getStringArray(ADAPTER_FROM));
//use spinner.setAdapter to set created adapter.
spinnerFrom.setAdapter (fromAdapter)
spinnerTo.setAdapter (toAdapter)
这仍然不能像我所希望的那样正常工作,但是如果你想在旋转屏幕上保存微调器状态,你可以尝试使用这个逻辑。Spnner有onNothingSelected方法。
在该方法中,尝试使用spinneradapter.getLastVisiblePosition。
当你关闭应用程序时,保存最后一个位置,当你回来时,使用最后一个位置。
希望有帮助。您可以使用两种方法来实现这一点。1建议使用ViewModels架构组件2使用保存和还原状态 一,。您可以创建viewModel,并且每当用户选择某个对象时,都可以使用指定的值调用viewModel。通过观察ViewModel,即使在旋转更改之后,也可以获得该值的最新更改,因为ViewModel将保持活动状态 3将用户的选择保留在“活动”中的局部变量中,然后在“保存和还原”中,按如下方式放置和获取值:
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("firstSpinnerPosition", variableThatHasTheChangedPosition);
savedInstanceState.putInt("secondSpinnerPosition", variableThatHasTheChangedPositionForSecond);
// other stuff.
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
variableThatHasTheChangedPosition = savedInstanceState.getInt("firstSpinnerPosition");
variableThatHasTheChangedPositionForSecond = savedInstanceState.getInt("secondSpinnerPosition");
//notify your adapter of the changes
}
我不能理解最后一个,它不等于我在代码中写的吗?正如我所写的-当用户单击按钮时,适配器会被填充,当屏幕旋转后,微调器中的任何活动适配器都会变为空。因此,我必须将适配器保存在onSaveInstanceState中,并在应用程序调用onRestoreInstanceState时调用spinner.setAdapter?您确定您有自己的项目,并且在调用onRestoreInstanceState时您的适配器已准备好使用吗?如果没有,则必须将从onRestoreInstanceState获取的信息放入某个变量中,然后在初始化和填充适配器后,相应地设置它们的值。是否确实已准备好项目,并且在调用onRestoreInstanceState时适配器已准备好使用?-不,当应用程序恢复自身时-它看不到任何适配器,因为它们不会创建onCreate memthod,所以即使使用保存的getSelectedItemPosition,它也不会执行任何操作。所以我必须保存活动适配器,比如adapter adapter=spinnerfrom.getAdapter?然后将保存的适配器设置为onRestoreInstanceState?您需要以某种方式保存项目,而不是保存适配器本身-使用捆绑包或任何可以保存项目并使用项目创建适配器的东西。如果您不能这样做,您可以将所选位置保存在变量中,并在数据准备就绪时使用它。很高兴你明白了。
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("firstSpinnerPosition", variableThatHasTheChangedPosition);
savedInstanceState.putInt("secondSpinnerPosition", variableThatHasTheChangedPositionForSecond);
// other stuff.
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
variableThatHasTheChangedPosition = savedInstanceState.getInt("firstSpinnerPosition");
variableThatHasTheChangedPositionForSecond = savedInstanceState.getInt("secondSpinnerPosition");
//notify your adapter of the changes
}