Пожалуйста, поправьте меня, если я ошибаюсь в этом. Это своего рода уточняющий вопрос, поскольку я не видел его явно написанным где-либо.
В Android 4 вы можете вызвать setRetainInstance(true)
на Fragment
, чтобы при изменении конфигурации (что в основном означает вращение устройства), java-объект Fragment
не был уничтожен, а новый экземпляр его не был создано. То есть экземпляр сохраняется.
Это гораздо более разумно и менее бесит, чем в Android 1-3, поскольку вам не нужно иметь дело с onRetainNonConfiguration
State
Instance()
и собирать все ваши данные, чтобы он может быть передан в новый экземпляр Fragment
(или Activity
) только для повторного разделения. Это в основном то, что вы ожидали бы, и, возможно, как он должен был работать с Activity
с самого начала.
С setRetainInstance(true)
вид также воссоздается (onCreateView()
вызывается) при вращении, как вы ожидали. И я предполагаю (не проверено), что разрешение ресурсов (layout
vs layout-land
) работает.
Итак, мой вопрос в два раза:
- Почему это было не так с
Activities
с самого начала. - Почему это не по умолчанию? Есть ли какая-либо причина, по которой вы действительно хотите, чтобы ваш
Fragment
был бесцельно уничтожен и воссоздан при ротации? Потому что я не могу придумать.
Изменить
Чтобы выяснить, как я это сделаю:
class MyFragment extends Fragment
{
// All the data.
String mDataToDisplay;
// etc.
// All the views.
TextView mViewToDisplayItIn;
// etc.
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true);
mDataToDisplay = readFromSomeFileOrWhatever(); // Ignoring threading issues for now.
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.my_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
// At this point if mViewToDisplayItIn was not null, the old one will be GC'd.
mViewToDisplayItIn = view.findViewById(R.id.the_text_view);
mViewToDisplayItIn.setText(mDataToDisplay);
}
// Optionally:
@Override
public void onDestroyView()
{
// All the view (and activity) to be GC'd.
mViewToDisplayItIn = null;
}
}