para - manual de programacion android pdf
Asignación de fragmentos a pestañas en la barra de acción con diferentes orientaciones (6)
¡Esto funciono muy bien para mi! Tuve este problema donde las actividades se superponían cada vez que cambiaba las pestañas:
mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
if (mFragment != null && !mFragment.isDetached()) {
FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
ft.detach(mFragment);
ft.commit();
¡Gracias de nuevo!
Tengo 3 fragmentos y una actividad. Quiero habilitar las pestañas en la ActionBar
y asignar un Fragment
a cada una de las 3 pestañas. ¿Cómo puedo conectar eso correctamente?
POSTE ORIGINAL
Tengo una aplicación que estoy desarrollando usando la aplicación Google I / O como guía. He implementado pestañas en la ActionBar
. Parecen estar funcionando hasta que cambia la orientación de la tableta. Por ejemplo, las 3 pestañas tienen un Fragment
. Puedo cambiar entre ellos muy bien, pero cuando cambio la orientación, cualquiera que sea el Fragment
vi por última vez permanece visible, pero al hacer clic en las pestañas ya no se cambia la vista ... como si se hubieran desconectado. Como se esperaba, volver a la orientación original no lo "arregla".
He investigado el estado de salvar y restaurar, pero no veo cómo eso ayudaría.
EDITAR
nivel de módulo:
Fragment mFragmentA = (Fragment) new AFragmentTab();
Fragment mFragmentB = (Fragment) new BFragmentTab();
Fragment mFragmentC = (Fragment) new CFragmentTab();
Tengo algo como esto en la actividad de onCreate
:
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(false);
ActionBar.Tab tabA = actionBar.newTab().setText("text a");
ActionBar.Tab tabB = actionBar.newTab().setText("text b");
ActionBar.Tab tabC = actionBar.newTab().setText("text c");
tabA.setTabListener(this);
tabB.setTabListener(this);
tabC.setTabListener(this);
actionBar.addTab(tabA);
actionBar.addTab(tabB);
actionBar.addTab(tabC);
y un TabListener
como este:
EDITAR esto se elimina
class MyTabListener implements ActionBar.TabListener {
private Fragment mFragment;
// Called to create an instance of the listener when adding a new tab
public MyTabListener(Fragment fragment) {
mFragment = fragment;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.add(R.id.fragment_content, mFragment, null);
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(mFragment);
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// do nothing
}
}
EDITAR
He movido el TabListener
. En lugar de ser una clase separada, implemento el TabListener
en la Activity
. Luego, en los métodos Selected
y no Selected
tengo algo como:
public void onTabSelected(Tab tab, FragmentTransaction ft) {
switch (tab.getPosition()) {
case 0:
ft.add(R.id.fragment_content, mFragmentA, null);
break;
case 1:
ft.add(R.id.fragment_content, mFragmentB, null);
break;
case 2:
ft.add(R.id.fragment_content, mFragmentC, null);
break;
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
switch (tab.getPosition()) {
case 0:
ft.remove(mFragmentA);
break;
case 1:
ft.remove(mFragmentB);
break;
case 2:
ft.remove(mFragmentC);
break;
}
}
Sigue haciendo lo mismo. Realmente no sé lo que está pasando.
Cree un nuevo proyecto de ejemplo de Android, elija el ejemplo de Support4Demos. Encontrará la muestra FragmentTabs allí.
El enlace proporcionado por @Metallicraft está muerto, así que aquí hay ayuda para aquellos que todavía se encuentran en esta publicación. Vaya here para obtener ayuda con la implementación de pestañas.
Para ver / leer el ejemplo original, puede ir a la siguiente carpeta si ha instalado el entorno de desarrollo de Android: android-sdk/samples/android-14/ApiDemos/src/com/example/android/apis/app/FragmentTabs.java
Además, si tiene problemas con la superposición de fragmentos después de la orientación, su cambio se relaciona correctamente con el estado guardado guardado. Aquí hay una copia pegada de un tutorial de Google que explica el problema de la superposición de fragmentos y cómo evitarlo:
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {
// However, if we''re being restored from a previous state,
// then we don''t need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
// Create an instance of ExampleFragment
HeadlinesFragment firstFragment = new HeadlinesFragment();
// In case this activity was started with special instructions from an Intent,
// pass the Intent''s extras to the fragment as arguments
firstFragment.setArguments(getIntent().getExtras());
// Add the fragment to the ''fragment_container'' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}
}
}
Parece que mi respuesta se puede encontrar aquí: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.html
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.app;
import com.example.android.apis.R;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.widget.Toast;
/**
* This demonstrates the use of action bar tabs and how they interact
* with other action bar features.
*/
public class FragmentTabs extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
bar.addTab(bar.newTab()
.setText("Simple")
.setTabListener(new TabListener<FragmentStack.CountingFragment>(
this, "simple", FragmentStack.CountingFragment.class)));
bar.addTab(bar.newTab()
.setText("Contacts")
.setTabListener(new TabListener<LoaderCursor.CursorLoaderListFragment>(
this, "contacts", LoaderCursor.CursorLoaderListFragment.class)));
bar.addTab(bar.newTab()
.setText("Apps")
.setTabListener(new TabListener<LoaderCustom.AppListFragment>(
this, "apps", LoaderCustom.AppListFragment.class)));
bar.addTab(bar.newTab()
.setText("Throttle")
.setTabListener(new TabListener<LoaderThrottle.ThrottledLoaderListFragment>(
this, "throttle", LoaderThrottle.ThrottledLoaderListFragment.class)));
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}
public static class TabListener<T extends Fragment> implements ActionBar.TabListener {
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
private final Bundle mArgs;
private Fragment mFragment;
public TabListener(Activity activity, String tag, Class<T> clz) {
this(activity, tag, clz, null);
}
public TabListener(Activity activity, String tag, Class<T> clz, Bundle args) {
mActivity = activity;
mTag = tag;
mClass = clz;
mArgs = args;
// Check to see if we already have a fragment for this tab, probably
// from a previously saved state. If so, deactivate it, because our
// initial state is that a tab isn''t shown.
mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
if (mFragment != null && !mFragment.isDetached()) {
FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
ft.hide(mFragment);
ft.commit();
}
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs);
ft.add(android.R.id.content, mFragment, mTag);
} else {
ft.show(mFragment);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
ft.hide(mFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Toast.makeText(mActivity, "Reselected!", Toast.LENGTH_SHORT).show();
}
}
}
Tenía más o menos el mismo problema, pero las soluciones presentadas anteriormente no parecían funcionar en mi situación. Finalmente encontré la siguiente solución:
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.replace(android.R.id.content, mFragment, mTag); // Use replace iso add
}
else {
ft.attach(mFragment);
}
}
@Override
public void onTabSelected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction fragmentTransaction) {
// Check if the fragment is already initialized
if (mFragment == null) {
// If not, instantiate and add it to the activity
// Toast.makeText(getApplicationContext(),"TAb "+tab.getPosition(),Toast.LENGTH_LONG).show();
if(tab.getPosition() == 1) {
mFragment = new HolderFragment();
fragmentTransaction.add(android.R.id.content, mFragment, mTag);
}
else if(tab.getPosition() == 0)
{
mFragment = new FragmentKnowledge();
fragmentTransaction.add(android.R.id.c`enter code here`ontent, mFragment, mTag);
}
/*else
{
mFragment = Fragment.instantiate(mActivity, mClass.getName());
fragmentTransaction.add(android.R.id.content, mFragment, mTag);
}
*/
} else {
// If it exists, simply attach it in order to show it
fragmentTransaction.attach(mFragment);
}
}