Lorsque je montre un fragment (plein écran avec #77000000
fond) sur un autre fragment (appelons-le principal), mon fragment principal réagit toujours aux clics (nous pouvons cliquer sur un bouton même si nous ne le voyons pas. il).
Question: comment empêcher les clics sur le premier fragment (principal)?
EDIT
Malheureusement, je ne peux pas simplement cacher le fragment principal, car j'utilise un arrière-plan transparent sur le second fragment (pour que l'utilisateur puisse voir ce qui se trouve derrière).
Définissez la propriété clickable
sur la vue du deuxième fragment sur true. La vue capturera l'événement afin qu'il ne soit pas transmis au fragment principal. Donc, si la vue du deuxième fragment est une mise en page, ce serait le code:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:clickable="true" />
La solution est assez simple. Dans notre deuxième fragment (qui recouvre notre fragment principal), nous devons juste attraper l'événement onTouch
:
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstance){
View root = somehowCreateView();
/*here is an implementation*/
root.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
return root;
}
Ajoutez simplement clickable="true"
et focusable="true"
à la mise en page parente
<Android.support.constraint.ConstraintLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:clickable="true"
Android:focusable="true">
<!--Your views-->
</Android.support.constraint.ConstraintLayout>
Si vous utilisez AndroidX
, essayez ceci
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:clickable="true"
Android:focusable="true">
<!--Your views-->
</androidx.constraintlayout.widget.ConstraintLayout>
Vous devez masquer le premier fragment lorsque vous affichez le second fragment si deux fragments sont placés dans la même vue de conteneur.
Si vous souhaitez en savoir plus sur la résolution des problèmes liés à Fragment, vous pouvez consulter ma bibliothèque: https://github.com/JustKiddingBaby/FragmentRigger
FirstFragment firstfragment;
SecondFragment secondFragment;
FragmentManager fm;
FragmentTransaction ft=fm.beginTransaction();
ft.hide(firstfragment);
ft.show(secondFragment);
ft.commit();
Vous devez ajouter Android:focusable="true"
avec Android:clickable="true"
Clickable
signifie qu'il peut être cliqué par un périphérique de pointage ou tapé par un périphérique tactile.
Focusable
signifie qu'il peut obtenir le focus d'un périphérique d'entrée tel qu'un clavier. Les périphériques d'entrée tels que les claviers ne peuvent pas choisir la vue à laquelle envoyer leurs événements d'entrée en fonction des entrées elles-mêmes. Ils les envoient donc à la vue active.
Cela ressemble à un cas pour DialogFragment. Sinon, avec Fragment Manager, engagez-en un à masquer et un autre à afficher. Cela a fonctionné pour moi.
J'ai eu plusieurs fragments avec le même XML.
Après avoir passé des heures, j'ai enlevé setPageTransformer
et ça a commencé à fonctionner
// viewpager.setPageTransformer(false, new BackgPageTransformer())
J'avais une logique décriante.
public class BackgPageTransformer extends BaseTransformer {
private static final float MIN_SCALE = 0.75f;
@Override
protected void onTransform(View view, float position) {
//view.setScaleX Y
}
@Override
protected boolean isPagingEnabled() {
return true;
}
}
Ce que vous pouvez faire, c’est que vous pouvez donner un clic vide à la disposition du fragment précédent en utilisant la propriété onClick pour mettre en page la disposition de ce fragment principal. En activité, vous pouvez créer une fonction doNothing(View view)
sans y écrire quoi que ce soit. Cela le fera pour vous.
L'ajout de Android:clickable="true"
n'a pas fonctionné pour moi. Cette solution ne fonctionne pas sur CoordinatorLayout lorsqu'il s'agit d'une disposition parent. C'est pourquoi j'ai créé RelativeLayout en tant que disposition parent, y ai ajouté Android:clickable="true"
et placé CoordinatorLayout sur ce RelativeLayout.
La réponse acceptable "fonctionnera", mais entraînera également un coût en performances (sur-découvert, nouvelle mesure en fonction du changement d'orientation) car le fragment situé en bas est toujours en cours de tracé. Peut-être devriez-vous simplement trouver le fragment par balise ou ID et définir la visibilité sur GONE ou VISIBLE lorsque vous devrez le montrer à nouveau.
À Kotlin:
fragmentManager.findFragmentByTag(BottomFragment.TAG).view.visibility = GONE
Cette solution est préférable aux méthodes alternatives hide()
et show()
de FragmentTransaction
lorsque vous utilisez des animations. Vous l'appelez simplement à partir de onTransitionStart()
et onTransitionEnd()
de Transition.TransitionListener
.