Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Barra de acciones de Android La pestaña con scrollview hizo una vista duplicada después del cambio de orientación

Tengo un código muy simple donde uso la barra de la acción con los fragmentos de la lengüeta. Funciona bien después de la carga, pero después del cambio de orientación se vuelve loco. El fragmento antiguo también es visible (¿por qué?).

Lo siento por los textos húngaros en la imagen, pero espero que no importa. Después del cambio de orientación

Adjunto el código, tal vez ayude a resolver este problema.

Actividad principal:

public class Main extends Activity { private static ActionBar actionBar; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setup action bar for tabs actionBar = getActionBar(); actionBar.removeAllTabs(); if (actionBar.getTabCount() == 0) { actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); Tab tab = actionBar.newTab().setText(R.string.starter).setTabListener(new TabListener<Starter>(this, "starter", Starter.class)); actionBar.addTab(tab); tab = actionBar.newTab().setText(R.string.newword).setTabListener(new TabListener<NewWord>(this, "newwod", NewWord.class)); actionBar.addTab(tab); tab = actionBar.newTab().setText(R.string.feedback).setTabListener(new TabListener<Feedback>(this, "feedback", Feedback.class)); actionBar.addTab(tab); } if (savedInstanceState != null) { actionBar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0)); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("tab", getActionBar().getSelectedNavigationIndex()); } } 

TabListener (igual que el ejemplo de Google):

 public class TabListener<T extends Fragment> implements android.app.ActionBar.TabListener { private Fragment mFragment; private final Activity mActivity; private final String mTag; private final Class<T> mClass; /** * Constructor used each time a new tab is created. * * @param activity * The host Activity, used to instantiate the fragment * @param tag * The identifier tag for the fragment * @param clz * The fragment's Class, used to instantiate the fragment */ public TabListener(Activity activity, String tag, Class<T> clz) { mActivity = activity; mTag = tag; mClass = clz; } @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { // User selected the already selected tab. Usually do nothing. } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { // Check if the fragment is already initialized if (mFragment == null) { // If not, instantiate and add it to the activity mFragment = Fragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content, mFragment, mTag); } else { // If it exists, simply attach it in order to show it ft.attach(mFragment); } } @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { if (mFragment != null) { // Detach the fragment, because another one is being attached ft.detach(mFragment); } } } 

Fragmento:

 public class Starter extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { setRetainInstance(false); return inflater.inflate(R.layout.newword, container, false); } } 

Y la disposición XML:

 <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="5dp" > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp" android:text="@string/newword" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/newwordtext" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/wordhint" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp" android:text="@string/description" android:textAppearance="?android:attr/textAppearanceMedium" android:textStyle="bold" /> <EditText android:id="@+id/descriptionwordtext" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/descriptionhint" android:inputType="textMultiLine" android:minLines="4" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp" android:text="@string/origin" android:textAppearance="?android:attr/textAppearanceMedium" android:textStyle="bold" /> <EditText android:id="@+id/origintext" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/originhint" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp" android:text="@string/source" android:textAppearance="?android:attr/textAppearanceMedium" android:textStyle="bold" /> <EditText android:id="@+id/sourcetext" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/sourcehint" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp" android:text="@string/name" android:textAppearance="?android:attr/textAppearanceMedium" android:textStyle="bold" /> <EditText android:id="@+id/nametext" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="textPersonName" /> <Button android:id="@+id/sendbutton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:text="@string/send" /> </LinearLayout> </ScrollView> 

¡Gracias de antemano!

  • Orientación de la captura de la cámara en dispositivos samsung en android
  • Cambio de fragmentos o actividades (es decir, diseños) en el cambio de orientación
  • Quiero hacer mi aplicación sólo en el paisaje en android
  • 5 Solutions collect form web for “Barra de acciones de Android La pestaña con scrollview hizo una vista duplicada después del cambio de orientación”

    Encontré una respuesta utilizable en otra pregunta .

    Necesito modificar mi TabListener (lo trasladé a mi clase de actividad principal como clase interna):

     private class TabListener<T extends Fragment> implements android.app.ActionBar.TabListener { private Fragment mFragment; private final Activity mActivity; private final String mTag; private final Class<T> mClass; /** * Constructor used each time a new tab is created. * * @param activity * The host Activity, used to instantiate the fragment * @param tag * The identifier tag for the fragment * @param clz * The fragment's Class, used to instantiate the fragment */ public TabListener(final Activity activity, final String tag, final Class<T> clz) { mActivity = activity; mTag = tag; mClass = clz; } @Override public void onTabReselected(final Tab tab, final FragmentTransaction ft) { // User selected the already selected tab. Usually do nothing. } @Override public void onTabSelected(final Tab tab, final FragmentTransaction ft) { mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag); if (mFragment == null) { mFragment = Fragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content, mFragment, mTag); } else { ft.attach(mFragment); } } @Override public void onTabUnselected(final Tab tab, final FragmentTransaction ft) { if (mFragment != null) { ft.detach(mFragment); } } } 

    Así que antes de añadir el fragmento (de nuevo), comprobar existance (y obtener su referencia) y si existe lo adjunto sólo.

    Intente usar ft.replace (R.id.content, mFragment) en lugar de ft.attach (mFragment); En la función onTabSelected

    He encontrado una solución muy simple para evitar la duplicación de fragmentos:

      public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { Fragment currentFragment = getFragmentManager().findFragmentByTag(CURRENT_FRAGMENT_TAG); if (currentFragment == null || !currentFragment.getClass().equals(mFragment.getClass())) { ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); ft.add(android.R.id.content, mFragment, CURRENT_FRAGMENT_TAG); } } public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); ft.remove(mFragment); } 

    La clave de la solución está en la condición:

     currentFragment == null || !currentFragment.getClass().equals(mFragment.getClass()) 

    Esta condición es válida SOLAMENTE si las clases de los fragmentos son diferentes. En el caso de que tengas diferentes instancias de la misma clase, debes poner un atributo extra en tus fragmentos para reconocer su función (o la asociación con y para hacer la condición! CurrentFragment.getClass (). Igual (mFragment.getClass ()) true : Por ejemplo, puede utilizar la función de etiqueta FragmentTransaction.

    Adiós, Alex.

     public void onTabSelected(Tab tab, FragmentTransaction ft) { // Check if the fragment is already initialized if (mFragment == null) { if(ft.findFragmentById(android.R.id.content) == null){ // If not, instantiate and add it to the activity mFragment = Fragment.instantiate(mActivity, mClass.getName()); ft.add(android.R.id.content, mFragment, mTag); } } else { // If it exists, simply attach it in order to show it ft.attach(mFragment); } } 

    Algo así, porque su problema es que su agregar el mismo fragmento dos veces, sólo tenemos que encontrar dónde …

    Resuelvo esto simplemente buscando el fragmento en el constructor de escuchas de tabulación.

     public class TabListener<T extends Fragment> implements ActionBar.TabListener { private Fragment fragment; private final SherlockFragmentActivity activity; private final String tag; private final Class<T> clazz; public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clazz) { this.activity = activity; this.tag = tag; this.clazz = clazz; FragmentManager manager = ((SherlockFragmentActivity) activity).getSupportFragmentManager(); fragment = manager.findFragmentByTag(tag); } ... } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.