Оба существующих ответа с использованием ViewModels и ручной обработки configChange действительно помогают.
Однако лично я был бы осторожен с настройкой configChanges в манифесте. Даже документация предупреждает:
Предупреждение. Обработка изменений конфигурации может значительно усложнить использование альтернативных ресурсов, поскольку система не применяет их автоматически для вас. Эту технику следует рассматривать как последнее средство, когда необходимо избегать перезапусков из-за изменения конфигурации, и она не рекомендуется для большинства приложений.
Использование ViewModel действительно было бы отличным способом для общей обработки изменения ориентации , Однако можно утверждать, что он не подходит для вашего сценария, поскольку вы динамически создаете представления, а модель представления не должна знать об этих представлениях.
В любом случае, вот как я справлюсь с этим в вашей ситуации:
- Прежде всего сохраните идентификаторы ваших
EditText
в ArrayList<Int>
- При добавлении нового EditText просто установите свой идентификатор в размер вашего списка идентификаторов и добавьте элемент в список со значением его размера
- Затем в onSaveInstanceState добавьте эти идентификаторы в свой набор сохраненных файлов InstanceState (используя функцию putIntegerArrayList таким образом, вам не нужно сохранять каждый идентификатор отдельно)
- В onCreate просто проверьте, является ли SavedInstanceState нулевым или нет
- Если значение параметра saveInstanceState не нулевое, получите идентификаторы из него и выполните итерацию по ним, создавая EditText для каждого идентификатора (так же, как при нажатии кнопки)
- Это все, что нужно сделать :)
Так же, как крошечная справочная информация: при вращении устройства , действие воссоздается, что означает, что все программно добавленные представления «пропали» (поскольку макет снова раздувается). Но если вы добавите эти виды с соответствующим идентификатором снова, состояние сохранится.
Достаточно поговорить здесь:
public class MainActivity extends AppCompatActivity {
private LinearLayout lnrDynamicEditTextHolder;
private EditText edtNoCreate;
private Button btnCreate;
private static final String KEY_IDS = "IDS";
List<EditText> allEditText = new ArrayList<EditText>();
ArrayList<Integer> allIds = new ArrayList<Integer>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lnrDynamicEditTextHolder = (LinearLayout) findViewById(R.id.lnrDynamicEditTextHolder);
btnCreate = (Button) findViewById(R.id.btnCreate);
edtNoCreate = (EditText) findViewById(R.id.edtNoCreate);
if (savedInstanceState != null) {
allIds = savedInstanceState.getIntegerArrayList(KEY_IDS)
for (int i=0;i<allIds.size();i++){
EditText editText = new EditText(MainActivity.this);
editText.setId(allIds.get(i));
editText.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
allEditText.add(editText);
lnrDynamicEditTextHolder.addView(editText);
}
}
btnCreate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try{
if(edtNoCreate.getText().toString().length()>0 && parseInt(edtNoCreate.getText().toString())!=0) {
if(edtNoCreate.getText().toString().length()==0){
edtNoCreate.setError("This Item Cannot be Empty");
return;
}
allEditText.clear();
lnrDynamicEditTextHolder.removeAllViews();
int length = parseInt(edtNoCreate.getText().toString());
for (int i=0;i<length;i++){
EditText editText = new EditText(MainActivity.this);
editText.setId(allIds.size());
allIds.add(allIds.size());
editText.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
allEditText.add(editText);
lnrDynamicEditTextHolder.addView(editText);
}
}
} catch (Throwable e) {
e.printStackTrace();
edtNoCreate.setError("This Item Cannot be Empty");
}
}
});
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putIntegerArrayList(KEY_IDS, allIds);
}
}