Зачем мне когда-либо хотеть `setRetainInstance (false)`? - Или - Правильный способ справиться с вращением устройства
Please correct me if I'm wrong on any of this. This is a kind of clarifying question since I haven't seen it explicitly written anywhere.
В Android 4 можно звонитьsetRetainInstance(true)
наFragment
так что при изменении конфигурации (что в основном означает вращение устройства),Fragment
Java-объект не уничтожен, и его новый экземпляр не создан. То есть экземпляр сохраняется.
Это намного более вменяемое и менее раздражающее, чем в Android 1-3, так как вам не приходится иметь дело сonRetainNonConfiguration
State
Instance()
и связать все ваши данные, чтобы они могли быть переданы в новыйFragment
(или жеActivity
) экземпляр только для того, чтобы быть отделенным снова. Это в основном то, что вы ожидаете, и, возможно, как это должно было работать дляActivity
с самого начала.
СsetRetainInstance(true)
вид тоже воссоздан (onCreateView()
называется) на вращение, как и следовало ожидать. И я предполагаю (не проверено), что разрешение ресурсов (layout
противlayout-land
) работает.
Итак, мой вопрос состоит из двух частей:
Why wasn't it like this withActivities
from the beginning.
Why isn't this the default? Is there ever any reason why you would actually want your Fragment
to be pointlessly destroyed and recreated on rotation? Because I can't think of any.
Edit
Чтобы уточнить, как я это сделаю:
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;
}
}