Android: problème de chevauchement de fragments
je suis confronté à un problème de fragments qui se chevauchent lorsque je passe d'un onglet à l'autre et que je fixe des fragments à un onglet ci-dessous est mon code s'il vous plaît aide
public class FragmentManage extends Fragment implements ActionBar.TabListener {
private Fragment mFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_manage, container, false);
OnClickListener clickListener = new OnClickListener() {
public void onClick(View v) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
switch(v.getId()) {
case R.id.imageBtnCategory:
if (mFragment == null){
mFragment = new FragmentCategory();
}
ft.replace(android.R.id.content, mFragment);
break;
case R.id.imageBtnManageKey:
if (mFragment == null){
mFragment = new FragmentKeys();
}
ft.replace(android.R.id.content, mFragment);
break;
case R.id.imageBtnChangePswd:
if (mFragment == null){
mFragment = new FragmentChangePwd();
}
ft.replace(android.R.id.content, mFragment);
break;
}
ft.commit();
}
};
ImageButton imageBtnCategory = (ImageButton) v.findViewById(R.id.imageBtnCategory);
ImageButton imageBtnManageKey = (ImageButton) v.findViewById(R.id.imageBtnManageKey);
ImageButton imageBtnChangePswd = (ImageButton) v.findViewById(R.id.imageBtnChangePswd);
imageBtnCategory.setOnClickListener(clickListener);
imageBtnManageKey.setOnClickListener(clickListener);
imageBtnChangePswd.setOnClickListener(clickListener);
return v;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mFragment = new FragmentManage();
ft.add(android.R.id.content, mFragment);
ft.attach(mFragment);
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(mFragment);
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
15 réponses
il suffit de définir une couleur de fond à votre <fragment />
dans le fichier XML.
résout le problème.
je peux être très en retard pour répondre à cette question.
Note:
cette réponse n'est peut-être pas liée à la question ci-dessus, mais j'espère qu'elle aidera certains.
parfois, la question du chevauchement de fragments se produit lorsque nous essayons d'utiliser les différents types de fragments( I. e utilisant des fragments de support dans quelques fragments et des fragments normaux dans un autre fragment)
J'ai récemment fait face à la même problème dans le tiroir de Navigation. Par erreur, j'ai utilisé" importation android.soutien.v4.App.Fragment; "dans un fragment, et utilisé" importation android.App.Fragment; " dans quelques autres fragments.
J'espère que cela aidera quelqu'un..
fragment manager maintient la pile de tous les fragments précédents qui sont remplacés parfois les fragments de la pile arrière se superpose avec le fragment que nous avons remplacé, pour moi
fragmentManager.popBackStack();
fonctionne, nous pouvons le faire dans une boucle aussi pour pop tous les fragments dans la pile espérons qu'il aide, merci. Heureux De Codage :)
bien configurer la couleur de fond du fragment n'est pas une solution parce que le fragment sera toujours dans la pile d'activité qui peut consommer de la mémoire.
Solution serait de supprimer toutes les vues de votre framelayout avant d'ajouter tout nouveau fragment.
private void changeFragment(Fragment fr){
FrameLayout fl = (FrameLayout) findViewById(R.id.mainframe);
fl.removeAllViews();
FragmentTransaction transaction1 = getSupportFragmentManager().beginTransaction();
transaction1.add(R.id.mainframe, fr);
transaction1.commit();
}
C'est comme ça que je l'ai réparé ..
définir l'arrière-plan supprimerait l'effet de chevauchement de l'écran seulement si la mise en page est appariée pour remplir l'écran
les nouveaux fragments remplacés par des clics de bouton ne sont pas remplacés par l'action tab_selected ou tab change
le code suivant l'a fixé pour moi
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// This is required since button click replaces fragment whose link is lost hence overlapping isuee was occuring
ft.replace(android.R.id.content, mFragment);
// On Tab Change remove old fragment views
ft.remove(mFragment);
}
un autre problème peut être lié à l'utilisation de android.R.id.content
comme conteneur. Je viens de créer FrameLayout
et d'utiliser id à partir de là.
j'ai aussi affronté un problème de chevauchement de fragments.Voici comment je l'ai résolu -
1) nous devons ajouter le premier fragment avec addToBackStack, de sorte qu'il soit retenu dans la pile -
FirstFragment firstFragment = new FirstFragment();
getFragmentManager().beginTransaction().add(R.id.fragment_container, firstFragment).addToBackStack("first frag").commit();
2) en ajoutant le second fragment, remplacer le premier fragment plutôt que de l'ajouter.Puisque le premier fragment a déjà été ajouté dans la pile, il sera donc présent lorsque vous appuyez sur retour du second fragment -
SecondFragment secondFragment= new SecondFragment();
getFragmentManager().beginTransaction().replace(R.id.fragment_container, secondFragment).addToBackStack("second frag").commit();
3) Voici comment back press peut être manipulé, ci-dessous le code doit être présent dans L'activité parent -
public void onBackPressed(){
if(getFragmentManager().getBackStackEntryCount() <= 1){
super.onBackPressed();
} else {
getFragmentManager().popBackStack();
}
}
private void changeFragment(Fragment fr){
FrameLayout fl = (FrameLayout) findViewById(R.id.mainframe);
fl.removeAllViews();
FragmentTransaction transaction1 =getSupportFragmentManager().beginTransaction();
transaction1.add(R.id.mainframe, fr);
transaction1.commit();}
quand vous avez un fragment de chevauchement, peut-être que votre fond de votre fragment est transparent, vous devez mettre un android: background= "@color / white" 'à l'intérieur de vos propeties de fragment
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
et blanc vous devez mettre à l'intérieur des couleurs.XML #FFFFFF dans le dossier rest.
j'ai parfois le même problème, mais mon problème n'est pas lié à différents fragment gestionnaires ( getSupportFragmentManager()
, getFragmentManager()
). Je pense qu'il ya encore un autre problème. Dans mon cas, quand j'ouvre le tiroir de navigation, j'efface toujours les vieux fragments sur chaque option de menu, par exemple:
Fragment calendarFragment = context.getSupportFragmentManager().findFragmentByTag(FragmentTag.CALENDAR.name());
if (calendarFragment != null)
{
context.getSupportFragmentManager().beginTransaction().remove(calendarFragment).commit();
}
il n'est pas possible d'entrer dans un sous-menu sans le tiroir de navigation, de sorte que les fragments sont essentiellement toujours enlevés. Dans certains cas, après avoir enlevé et ajouté un fragment de nouveau à l'intérieur d'une activité, il se superpose soudainement avec un autre fragment (précédent)?! Mais pourquoi le gestionnaire de fragments trouve-t-il soudainement des fragments antérieurs?
Cela peut signifier que le gestionnaire de fragments est bogué et qu'il n'enlève pas les vieux fragments, ou que quelque chose d'autre est cassé.
Ma pensée est, que c'est en quelque sorte la faute D'Android Studio ou tout autre outil de développement adb qui est utilisé par elle. Pourquoi je pense que c'est, parce que Android Studio semblent parfois perdre l'instance de l'application en cours d'exécution. Probablement ce problème est en quelque sorte liée à la même question: Android Studio ne déploie pas les changements à l'application . Je n'ai pas encore compris quand ça arrive. Ce que je sais, c'est que ça ne peut pas être un problème de programmation, parce que ce n'est pas reproductible après que j'ai relancé L'application par Android Studio. Je suppose qu'il y a d'une façon ou d'une autre n'importe quel processus de fond suspendu qui cause des instances multiples d'activités, de Fragments, de gestionnaires de fragments et ainsi de suite. En outre, il n'est pas seulement ce bug. J'ai vu beaucoup de comportements étranges dans le passé qui sont similaires à celui-ci. (Par exemple, les comportements ont soudainement disparu lorsque L'application N'a pas été lancée par IDE).
tout cela a à voir avec l'ingénierie derrière le remplacer et le addToBackStack méthodes.
La méthode de remplacement fera en fait deux choses. Masquer l'existant fragment (disons A) et en ajouter un nouveau (disons B) dans le récipient.
L'ajout de cette transaction à la pile arrière fera l'inverse. Supprimer B et ajouter A.
Donc, la solution à votre problème
1. utiliser la méthode addToBackStack .
2. assurez-vous que le remplacement inversé des fragments est l'ordre correct
La seconde suggestion est vraiment importante, car il arrive assez souvent qu'à un moment donné le fragment courant ne soit pas enlevé et qu'un autre soit ajouté, ce qui provoque l'apparition des deux fragments en même temps.
la couleur de fond blanc résolu pour moi aussi. Je pense que c'est un problème de bogue et d'implémentation dans le gestionnaire de fragment Android. J'implémentais mon replace et popBackStack() correctement.
quand j'ai eu un problème comme celui-ci, il est apparu que j'ajoutais un fragment avec childFragmentManager et un autre avec parent fragmentManager, donc vérifiez que vous utilisez le même type de gestionnaire de fragments.
Je ne pense pas que la mise en œuvre d'un fond blanc soit une solution sûre bien qu'elle puisse être pratique. Fondamentalement, le problème se produit parce que gestionnaire de fragment est confus au sujet de quel fragment à pop.
backstack ressemble à cela et pense que votre sur frag 4 1->2, 2->3, 3->4 mais votre réellement sur frag 6 pour une raison quelconque donc popbackstack va
supprimer(4) ajouter(3) <- maintenant, vous avez 3(nouveau) et 6(à gauche derrière), mélangés ensemble
pour mieux contrôler ma navigation, je garde la trace de mes fragments actuels/précédents et je les remplace comme ceci. Cela permet à mon application de contrôler la navigation des fragments.
if ( !(currentFragment instanceof Settings)) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, settings);
fragmentTransaction.addToBackStack(null);
previousFrag = currentFragment;
currentFragment = settings;
fragmentTransaction.commit();
}
deuxièmement, je crois le fragmentmanager.méthode replace() est une meilleure alternative. Je ne sais pas si C'est disponible pour L'OP à ce moment-là.
troisièmement, pour gérer les androïdes natif back press vous devez être en mesure de faire défiler vers l'arrière indéfiniment. Beaucoup de gens recommandent de ne pas ajouter le premier fragment à retourner stack en n'utilisant pas cette ligne.
fragmentTransaction.addToBackStack (null);
Toutefois si c'est le cas, vous devez vérifier si c'est la première fois que l'application est chargée. Si ce n'est pas et que vous excluez cette ligne, alors votre application aura ces problèmes à chaque fois que vous naviguez à travers ce fragment. Je préfère le laisser en place et faire ce qui suit à la place.
pas sûr si cela est considéré comme une bonne solution, mais il fonctionne très bien.
1 2-supprimer tous les cadres existants 3-Gardez une trace de vous fragmentez des objets 4-si c'est le dernier fragment de la pile que l'Utilisateur souhaite quitter et puisque nous avons ajouté l'activité principale à la pile arrière nous devons doubler pop
@Override
public void onBackPressed() {
int num = getFragmentManager().getBackStackEntryCount();
fl.removeAllViews();
super.onBackPressed();
if (currentFragment != previousFrag) {
currentFragment = previousFrag;
}else{
currentFragment = null;
}
if (num == 1){
super.onBackPressed();
}
j'ai trouvé une solution simple et propre. Pour moi le problème était dans la transaction de fragment d'exécution dans chaque appel d'onCreate() de mon activité. Maintenant j'effectue la transaction seulement si savedincastate = = null
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (savedInstanceState == null) {
// replace fragment
}
}