Usando el paquete de compatibilidad para apuntar a 2.2 usando Fragments.
Después de recodificar una actividad para usar fragmentos en una aplicación, no pude hacer que funcionaran los cambios de orientación / gestión de estado, así que creé una pequeña aplicación de prueba con un solo FragmentActivity y un solo Fragment.
Los registros de los cambios de orientación son extraños, con múltiples llamadas a los fragmentos OnCreateView.
Obviamente, me falta algo, como separar el fragmento y volver a adjuntarlo en lugar de crear una nueva instancia, pero no puedo ver ninguna documentación que indique dónde me estoy equivocando.
¿Alguien puede arrojar algo de luz sobre lo que estoy haciendo mal aquí, por favor? Gracias
El registro es el siguiente después de los cambios de orientación.
Initial creation
12-04 11:57:15.808: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:57:15.945: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:16.081: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null
Orientation Change 1
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:57:39.031: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:39.167: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null
Orientation Change 2
12-04 11:58:32.162: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:58:32.162: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:58:32.361: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:58:32.498: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.498: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null
Actividad principal (FragmentActivity)
public class FragmentTestActivity extends FragmentActivity {
/** Called when the activity is first created. */
private static final String TAG = "FragmentTest.FragmentTestActivity";
FragmentManager mFragmentManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(TAG, "onCreate");
mFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
FragmentOne fragment = new FragmentOne();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
Y el fragmento
public class FragmentOne extends Fragment {
private static final String TAG = "FragmentTest.FragmentOne";
EditText mEditText;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "OnCreateView");
View v = inflater.inflate(R.layout.fragmentonelayout, container, false);
// Retrieve the text editor, and restore the last saved state if needed.
mEditText = (EditText)v.findViewById(R.id.editText1);
if (savedInstanceState != null) {
Log.d(TAG, "OnCreateView->SavedInstanceState not null");
mEditText.setText(savedInstanceState.getCharSequence("text"));
}
else {
Log.d(TAG,"OnCreateView->SavedInstanceState null");
}
return v;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d(TAG, "FragmentOne.onSaveInstanceState");
// Remember the current text, to restore if we later restart.
outState.putCharSequence("text", mEditText.getText());
}
Manifiesto
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".activities.FragmentTestActivity"
android:configChanges="orientation">
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Respuestas:
Estás superponiendo tus Fragmentos uno encima del otro.
Cuando se produce un cambio de configuración, el fragmento antiguo se agrega a la nueva actividad cuando se vuelve a crear. Este es un gran dolor en el trasero la mayor parte del tiempo.
Puede evitar que se produzcan errores utilizando el mismo fragmento en lugar de volver a crear uno nuevo. Simplemente agregue este código:
Sin embargo, tenga cuidado: se producirán problemas si intenta acceder a las Vistas de actividad desde el interior del Fragmento, ya que los ciclos de vida cambiarán sutilmente. (Obtener vistas de una actividad principal a partir de un fragmento no es fácil).
fuente
"when the activity is destroyed, so are all fragments"
:? Desde que"When the screen orientation changes, the system destroys and recreates the activity [...]"
.Para citar este libro , "para garantizar una experiencia de usuario coherente, Android conserva el diseño de Fragmento y la pila de actividades asociada cuando se reinicia una actividad debido a un cambio de configuración". (pág.124)
Y la forma de abordar eso es verificar primero si la pila posterior de Fragmento ya se ha poblado y crear la nueva instancia de fragmento solo si no lo ha hecho:
fuente
El método onCreate () de su actividad se llama después del cambio de orientación como ha visto. Por lo tanto, no ejecute FragmentTransaction que agrega el Fragment después del cambio de orientación en su actividad.
Los Fragmentos deben y deben permanecer sin cambios.
fuente
Puede
@Override
utilizar FragmentActivityonSaveInstanceState()
. Asegúrese de no llamarsuper.onSaveInstanceState()
al método.fuente
Siempre debemos intentar evitar la excepción de puntero nulo, por lo que primero debemos verificar en el método saveinstance la información del paquete. para una breve explicación, consulte el enlace de este blog
fuente
Si solo hace un proyecto, entonces el gerente de proyecto dice que necesita lograr la función de cambio de pantalla, pero no desea cambiar la pantalla y cargar un diseño diferente (puede crear un diseño y un sistema de puerto de diseño.
Determinará automáticamente el estado de la pantalla, cargará el diseño correspondiente), debido a la necesidad de reiniciar la actividad o el fragmento, la experiencia del usuario no es buena, no directamente en el interruptor de pantalla, ¿me refiero? Url = YgNfP-vHy-Nuldi7YHTfNet3AtLdN-w__O3z1wLOnzr3wDjYo7X7PYdNyhw8R24ZE22xiKnydni7R0r35s2fOLcHOiLGYT9Qh_fjqtyfolcHOiLGYT9Qh_fjqtyt & e19q45 & wd85a85
La premisa es que su diseño use el peso de la forma en que el diseño del layout_weight, de la siguiente manera:
Entonces, mi enfoque es, cuando se cambia de pantalla, no es necesario cargar un nuevo diseño del archivo de vista, modificar el diseño en los pesos dinámicos onConfigurationChanged, los siguientes pasos: 1 primer conjunto: AndroidManifest.xml en el atributo de actividad: android: configChanges = "keyboardHidden | Orientación | screenSize" Para evitar el cambio de pantalla, evite volver a cargar, para poder monitorear en onConfigurationChanged 2 la actividad de reescritura o fragmento en el método onConfigurationChanged.
fuente
Al cambiar la configuración, el marco creará una nueva instancia del fragmento para usted y la agregará a la actividad. Entonces en lugar de esto:
hacer esto:
Tenga en cuenta que el marco agrega una nueva instancia de FragmentOne en el cambio de orientación a menos que llame a setRetainInstance (true), en cuyo caso agregará la instancia anterior de FragmentOne.
fuente