vertical studio solo rotar rotación rotacion reinicie que pantalla orientacion movil manejando lite horizontal girar forzar fijar evitar detectar como cambio bloquear aplicacion activity android checkbox rotation restore

solo - forzar pantalla horizontal android studio



Android CheckBox-Restaurando el estado después de la rotación de la pantalla (8)

He encontrado una funcionalidad muy inesperada (e increíblemente frustrante) al intentar restaurar el estado de una lista de CheckBox después de una rotación de pantalla. Pensé que primero trataría de dar una explicación textual sin el código, en caso de que alguien sea capaz de determinar una solución sin todos los detalles sangrientos. Si alguien necesita más detalles, puedo publicar el código.

Tengo una lista desplegable de View complejas que contienen CheckBox es. No he podido restablecer el estado de estas casillas de verificación después de una rotación de pantalla. Implementé onSaveInstanceState y transferí con éxito la lista de casillas de verificación seleccionadas al método onCreate . Esto se maneja pasando una long[] de identificadores de base de datos al Bundle .

En onCreate() el Bundle para la matriz de identificadores. Si la matriz está allí, la utilizo para determinar qué casillas de verificación verificar cuando se está construyendo la lista. He creado varios métodos de prueba y he confirmado que las casillas de verificación se están configurando correctamente, en función de la matriz de id. Como última comprobación, estoy verificando los estados de todas las casillas de verificación al final de onCreate( ). Todo se ve bien ... a menos que gire la pantalla.

Cuando giro la pantalla, ocurre una de estas dos cosas: 1) Si se selecciona cualquier número de casillas de verificación, excepto la última, todas las casillas de verificación están desactivadas después de una rotación. 2) Si se marca la última casilla de verificación antes de la rotación, todas las casillas de verificación se verifican después de la rotación.

Como dije, onCreate() el estado de las cajas al final de mi onCreate() . El caso es que el estado de las casillas al final de onCreate es correcto en función de lo que seleccioné antes de la rotación. Sin embargo, el estado de los cuadros en la pantalla no refleja esto.

Además, he implementado setOnCheckChangedListener() cada casilla de setOnCheckChangedListener() y he confirmado que el estado de mi casilla de verificación se está alterando después de que mi método onCreate regrese.

Alguien tiene una idea de lo que está pasando? ¿Por qué cambiaría el estado de mis casillas de verificación después de que mi método onCreate regrese?

Gracias de antemano por tu ayuda. He estado intentando degubar esto por un par de días. Cuando descubrí que mis casillas de verificación aparentemente cambiaban en algún lugar fuera de mi propio código, pensé que era hora de preguntar.


Hay una solución que es más fácil de explicar.

Android CHECKBOXES y RADIOBUTTON y RADIOGROUPS se comportan de manera extraña si el atributo "id" no está configurado en ellos.

Tenía exactamente el mismo problema en mi código, y después de colocar identificadores en casillas de verificación, comenzó a funcionar, sin tener que deshabilitar ninguno de los métodos de superclase.


Me he encontrado con esto también. Debería restaurar el estado de la casilla de verificación en onRestoreInstanceState () en lugar de onCreate ().

La actividad se destruye cuando cambia la orientación de la pantalla y se llama a onRestoreInstanceState () después de onCreate (). Dado que la implementación principal / predeterminada de onRestoreInstanceState () restaura automáticamente el estado en Views with IDs, está restaurando sus casillas de verificación después de onCreate () y destruyéndolas, aparentemente debido a que tienen la misma ID (¿error de framework?).

http://developer.android.com/reference/android/app/Activity.html

http://developer.android.com/reference/android/app/Activity.html#onRestoreInstanceState(android.os.Bundle)


Probablemente el problema es que cuando se onRestoreInstanceState(Bundle) restablece algunas o todas las "configuraciones" de su aplicación a los "valores predeterminados" de la puesta en marcha. La mejor manera de resolver esto es a través de llamadas y administración de métodos del ciclo de vida de la aplicación. Además, cada vez que se cambia algo en su aplicación que no desea perder, guarde el cambio en saveInstanceState(Bundle) o cree su propio Bundle() para mantener los cambios temporalmente hasta que pueda persistir los cambios en un archivo o algo, es bastante fácil pasar un paquete a través de una intención entre actividades. Cómo guarda lo que necesita guardar según el tiempo que necesita para conservar la "configuración".


Rpond, no he reemplazado en Reesume, así que no creo que ese sea el problema. Aquí está la Actividad y los diseños asociados para que todos puedan ver. En el código verá muchas instrucciones Log.d (hubo incluso más en un punto). Con estas declaraciones Log pude verificar que el código funciona exactamente como lo esperaba. Además, observe el onCheckChangedListener que agrego a cada CheckBox. Todo lo que hace es imprimir una declaración de registro que me dice que el estado de uno de mis cuadros de control ha cambiado. Fue a través de esto que pude determinar el estado de los CheckBoxes después de que mi onCreate regresara. Verás cómo llamo examineCheckboxes () al final de mi onCreate. Las declaraciones de Log producidas a partir de esto no son lo que se muestra en mi pantalla después de una rotación, y puedo ver el estado de mis cuadros después (debido a onCheckChangedListener).

SelectItems.java:

clase pública SelectItems extends Activity {

public static final int SUCCESS = 95485839; public static final String ITEM_LIST = "item list"; public static final String ITEM_NAME = "item name"; // Save state constants private final String SAVE_SELECTED = "save selected"; private DbHelper db; private ArrayList<Long> selectedIDs; ArrayList<CheckBox> cboxes = new ArrayList<CheckBox>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.select_items); // Create database helper db = new DbHelper(this); db.open(); initViews(savedInstanceState); examineCheckboxes(); } private void initViews(Bundle savedState) { initButtons(); initHeading(); initList(savedState); } private void initButtons() { // Setup event for done button Button doneButton = (Button) findViewById(R.id.done_button); doneButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { done(); } }); // Setup event for cancel button Button cancelButton = (Button) findViewById(R.id.cancel_button); cancelButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { cancel(); } }); } private void initHeading() { String itemName = getIntent().getExtras().getString(ITEM_NAME); TextView headingField = (TextView) findViewById(R.id.heading_field); if (itemName.equals("")) { headingField.setText("No item name!"); } else { headingField.setText("Item name: " + itemName); } } private void initList(Bundle savedState) { // Init selected id list if (savedState != null && savedState.containsKey(SAVE_SELECTED)) { long[] array = savedState.getLongArray(SAVE_SELECTED); selectedIDs = new ArrayList<Long>(); for (long id : array) { selectedIDs.add(id); } Log.d("initList", "restoring from saved state"); logIDList(); } else { selectedIDs = (ArrayList<Long>) getIntent().getExtras().get( ITEM_LIST); Log.d("initList", "using database values"); logIDList(); } // Begin building item list LayoutInflater li = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout scrollContent = (LinearLayout) findViewById(R.id.scroll_content); Cursor cursor = db.getAllItems(); startManagingCursor(cursor); cursor.moveToFirst(); // For each Item entry, create a list element while (!cursor.isAfterLast()) { View view = li.inflate(R.layout.item_element, null); TextView name = (TextView) view.findViewById(R.id.item_name); TextView id = (TextView) view.findViewById(R.id.item_id); CheckBox cbox = (CheckBox) view.findViewById(R.id.checkbox); name.setText(cursor.getString(cursor .getColumnIndexOrThrow(DbHelper.COL_ITEM_NAME))); final long itemID = cursor.getLong(cursor .getColumnIndexOrThrow(DbHelper.COL_ID)); id.setText(String.valueOf(itemID)); // Set check box states based on selectedIDs array if (selectedIDs.contains(itemID)) { Log.d("set check state", "setting check to true for " + itemID); cbox.setChecked(true); } else { Log.d("set check state", "setting check to false for " + itemID); cbox.setChecked(false); } cbox.setOnClickListener(new OnClickListener() { public void onClick(View v) { Log.d("onClick", "id: " + itemID + ". button ref: " + ((CheckBox) v)); checkChanged(itemID); } }); //I implemented this listener just so I could see when my //CheckBoxes were changing. Through this I was able to determine //that my CheckBoxes were being altered outside my own code. cbox.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton arg0, boolean arg1) { Log.d("check changed", "button: " + arg0 + " changed to: " + arg1); } }); cboxes.add(cbox); scrollContent.addView(view); cursor.moveToNext(); } cursor.close(); examineCheckboxes(); } private void done() { Intent i = new Intent(); i.putExtra(ITEM_LIST, selectedIDs); setResult(SUCCESS, i); this.finish(); } private void cancel() { db.close(); finish(); } private void checkChanged(long itemID) { Log.d("checkChaged", "checkChanged for: "+itemID); if (selectedIDs.contains(itemID)) { selectedIDs.remove(itemID); } else { selectedIDs.add(itemID); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); long[] array = new long[selectedIDs.size()]; for (int i = 0; i < array.length; i++) { array[i] = selectedIDs.get(i); } outState.putLongArray(SAVE_SELECTED, array); } //Debugging method used to see what is in selectedIDs at any point in time. private void logIDList() { String list = ""; for (long id : selectedIDs) { list += id + " "; } Log.d("ID List", list); } //Debugging method used to check the state of all CheckBoxes. private void examineCheckboxes(){ for(CheckBox cbox : cboxes){ Log.d("Check Cbox", "obj: "+cbox+" checked: "+cbox.isChecked()); } }

}

select_items.xml:

<?xml version="1.0" encoding="utf-8"?>

<TextView android:id="@+id/heading_field" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dip" android:textSize="18sp" android:textStyle="bold" /> <LinearLayout android:id="@+id/button_layout" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true"> <Button android:id="@+id/done_button" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Done" /> <Button android:id="@+id/cancel_button" android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel" /> </LinearLayout> <ScrollView android:orientation="vertical" android:layout_below="@id/heading_field" android:layout_above="@id/button_layout" android:layout_width="fill_parent" android:layout_height="wrap_content"> <LinearLayout android:id="@+id/scroll_content" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> </LinearLayout> </ScrollView>

item_element.xml:

<?xml version="1.0" encoding="utf-8"?>

<CheckBox android:id="@+id/checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="5dip" /> <TextView android:id="@+id/item_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:layout_centerVertical="true" android:layout_toLeftOf="@id/checkbox" android:layout_alignParentLeft="true" /> <TextView android:id="@+id/item_id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="invisible" />


Si alguna vez encuentras algo más sobre este problema, házmelo saber. onRestoreInstanceState() esencialmente este mismo problema, y ​​solo reemplazó onRestoreInstanceState() funcionó. Muy raro.


También puede usar onSaveInstanceState(Bundle savedInstanceState) y onRestoreInstanceState(Bundle savedInstanceState)

ejemplo

@Override public void onSaveInstanceState(Bundle savedInstanceState) { // EditTexts text savedInstanceState.putString("first_et",((EditText)findViewById(R.id.et_first)).getText().toString()); // EditTexts text savedInstanceState.putInt("first_et_v", ((EditText)findViewById(R.id.et_first)).getVisibility()); super.onSaveInstanceState(savedInstanceState); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); // EditTexts text ((EditText)findViewById(R.id.et_first)).setText(savedInstanceState.getString("first_et")); // EditText visibility ((EditText)findViewById(R.id.et_first)).setVisibility(savedInstanceState.getInt("first_et_v")); }


Tuve un problema similar. La aplicación tenía varias casillas de verificación en la pantalla.
Después de rotar la aplicación del teléfono, el valor de configuración ''manual'' para todas las casillas de verificación.
Este código se ejecutó en onStart ().
Pero en la pantalla, todas las casillas de verificación se configuraron con el valor de "última casilla de verificación" en la pantalla.
Android estaba llamando aRestoreInstanceState (..) y de alguna manera estaba tratando todas las casillas de verificación como ''uno'' [último de la pantalla].

La solución fue deshabilitar ''restaurar el estado de la instancia'':

<RadioButton ... android:saveEnabled="false" />


todo el mundo. Parece que descubrí esto. El estado de las casillas de verificación está siendo alterado en onRestoreInstanceState (Bundle). Este método se llama después de onCreate () (más precisamente, después de onStart ()), y es otro lugar donde Android recomienda restaurar el estado.

Ahora, no tengo idea de por qué mis casillas de verificación están siendo alteradas dentro de RestoreInstanceState, pero al menos sé que es donde está ocurriendo el problema. Sorprendentemente, cuando anulo en RestoreInstanceState y no hago absolutamente nada (sin invocar a super.onRestoreInstanceState) toda la actividad funciona perfectamente.

Si alguien puede decirme por qué se está cambiando el estado seleccionado de las casillas de verificación en este método, me gustaría saber mucho más. En mi opinión, esto parece un error dentro del código de Android en sí.