Swipe geste appliqué au niveau du Fragment avec ViewPager avec son swipe par défaut désactivé

j'ai trouvé la question ci-dessous: Android: FragmentActivity dans FragmentActivity (Scrollview dans Navigationbar) . Toutefois, ma question porte sur la façon d'utiliser les Transactions pour montrer des fragments ainsi que de permettre la détection de gestes par balayage d'une manière sûre. Note: il y a un lien dans la réponse que j'ai posté (cela a aussi la manière efficace de montrer des fragments dans un conteneur en utilisant des transactions, y compris deux scénarios). Veuillez voir que. J'ai essayé un peu de choses en ce qui concerne, mais en utilisant un fragment supportant ViewPager, Non emboîté:

détails: https://moqups.com/abhsax130778@gmail.com/lc0ZOERO/p:a5d7b55eb

  1. désactivé swipe par défaut en utilisant onTouchEvent et onintceptouchevent en utilisant custom ViewPager.
  2. a déclaré FragmentStatePagerAdapter fourni avec une liste de fragments, dont chacun est affiché dans chaque onglet.
  3. déclare les Fragments dans le main_layout de la main_activity qui a ce ViewPager le long du côté. L'idée est de montrer l'activity_fragments quand un bouton sur un ViewPager_fragment est cliqué et quand l'utilisateur appuie sur retour bouton, puis le ViewPager_fragment par défaut est montré à nouveau en utilisant les transactions de pile arrière sur add et les sautant sur BackPressed de l'activité. Je maintiens donc aussi mon backStack personnalisé pour montrer / cacher les activity_fragments lorsque la pile arrière pop une transaction.

maintenant, ce que je veux réaliser est de faire le troisième point ci-dessus en utilisant des gestes par glissement pour droite [de gauche à droite] seulement.

J'ai utilisé GestureListener et SimpleOnGestureListener et activit's OnTouchEvent pour cela.

le problème auquel je fais face est que:

ce geste fonctionne sur la partie de l'écran d'activité qui est sous le fragment et la partie de l'activité. Je veux que la geste travail

  1. sur Fragment dont la disposition présente plusieurs vues.
  2. dans la seule direction gauche-droite.
  3. Seulement à partir de activity_fragment à ViewPager onglet du fragment à se comporter comme l'historique de navigation, comme cela est déjà fait dans onBakPressed/onKeyDown implémentation en utilisant des popups de pile arrière et ma pile arrière personnalisée.

j'ai essayé la classe suivante et le changement dans mon activité fragment dans des layouts comme celui-ci.

mon auditeur gestuel et tactile étendu avec la mise en page de cadre:

        public class OnSwipeTouchListener extends FrameLayout {

        private final GestureDetector gestureDetector;
        private static final String TAG = "OnSwipeTouchListener";
    private Context context;
        public OnSwipeTouchListener(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.context=context;
            gestureDetector = new GestureDetector(context, new GestureListener());
            setClickable(true);

        }

        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            return super.onInterceptTouchEvent(ev);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
 gestureDetector.onTouchEvent(motionEvent);
            return super.onTouchEvent(event);
        }


        private final class GestureListener extends SimpleOnGestureListener {

            private static final int SWIPE_THRESHOLD = 100;
            private static final int SWIPE_VELOCITY_THRESHOLD = 100;

            @Override
            public boolean onDown(MotionEvent e) {

                return true;
            }

            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

                boolean result = false;
                try {
                    float diffY = e2.getY() - e1.getY();
                    float diffX = e2.getX() - e1.getX();
                    if (Math.abs(diffX) > Math.abs(diffY)) {
                        if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                            if (diffX > 0) {
                                onSwipeRight();
                            } else {
                                onSwipeLeft();
                            }
                        }
                    } else {
                        if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) >           SWIPE_VELOCITY_THRESHOLD) {
                            if (diffY > 0) {
                                onSwipeBottom();
                            } else {
                                onSwipeTop();
                            }
                        }
                    }
                } catch (Exception exception) {
                    //see that e1 is null
                }
                return result;
            }
        }

        public void onSwipeRight() {
            ///manage my back stack history here.
        }

        public void onSwipeLeft() {
        }

        public void onSwipeTop() {
        }

        public void onSwipeBottom() {
        }
    }

et modifier ensuite la disposition des cadres de référence pour cette classe:

<path.to.my.package.OnSwipeTouchListener
            android:id="@+id/activity_frag_frame_layout1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:visibility="invisible" >

            <fragment
                android:id="@+id/activity_frag1"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                class="path.to.my.package.fragments.Activity_Frag1"
                android:tag="act_frag1" />
        </path.to.my.package.OnSwipeTouchListener>

cela m'a peu aidé, donc devrait-il vous aider à trouver une solution. Il y a un searchView dans l'un des fragments qui a cessé de fonctionner, et aucun clic ne fonctionne. Si vous obtenez ce que je veux accomplir, s'il vous plaît aider à cet égard.

mise à jour 1: Returning true dans onTouchEvent et onceptcepttouchevent a l'effet désiré, mais il bloque les clics dans les fragments où SearchView est là, aucun clics de travail dans les vues cliquables présents. Seul le passage de travail. Mise à jour: dans mon dernier: j'ai également écarté l'utilisation de transaction-back-stacks complètement parce que je me fie à mon back-STACKS personnalisé où je maintiens l'historique de navigation pour tous les onglets. Pour ce faire, j'utilise la méthode setCurrentTab et les méthodes onTabSelected données par ViewPager et FragmentStatePagerAdapter.

mise à jour 2: Celui-ci est difficile à mettre en œuvre: Vérifier quels événements doivent être interceptés et lesquels doivent être transmis à l'opinion de l'enfant: http://developer.android.com/training/gestures/viewgroup.html

Maj 3:

  1. il y a un fragment.

  2. lorsque vous démarrez l'application, le viewPager affiche le fragment dans le premier onglet.

  3. Lorsqu'un bouton sur ce fragment est cliqué, l'un des fragments framelayouts below viewpager est affiché et ajouté à mon backstack personnalisé.

  4. lorsque la touche Retour Est Pressée, ce fragment est à nouveau caché pour afficher le fragment de l'onglet dans le viewPager. Tous les de la ci-dessus est fait. Seulement je veux le geste de glisser pour de gauche à droite pour travailler, et j'ai trouvé que je peux le faire en interceptant des événements tactiles. Mais il ne le fait pas du tout quand je reviens vrai, seul le geste de glisser fonctionne, sinon cette action est annulée et les clics sur ce fragment fonctionnent.

7
demandé sur Community 2013-09-16 10:40:40

1 réponses

j'ai mentionné cette réponse dans http://mobi-app-dev.blogspot.in/2014/01/android-transactions.html .

vérifier quels événements doivent être interceptés et lesquels doivent être transmis à l'opinion de l'enfant: http://developer.android.com/training/gestures/viewgroup.html

au lieu d'utiliser mon écouteur de geste par balayage quels fragments sont attachés, maintenant je l'utilise sur le les dispositions relatives qui sont la racine des vues de la fragment.

@Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        boolean intercepted = super.onInterceptTouchEvent(event);

        // In general, we don't want to intercept touch events. They should be
        // handled by the child view.

        gestureDetector.onTouchEvent(event);
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean touched = super.onTouchEvent(event);
        gestureDetector.onTouchEvent(event);
        return touched;
    }

voici quelques conseils que je suis maintenant en utilisant des fragments dans Mes activités:

la gestion Efficace des opérations de fragment:

[Note: dans le cas où vous utilisez FragmentStatePagerAdapter, vous pouvez jouer avec le remplacement d'un fragment par un autre fragment à un index particulier dans la liste de fragment que vous utilisez comme données pour cet adaptateur, dans une manière que vous êtes dans le même onglet, mais son contenu est modifié sans changer l'onglet. Utilisez ensuite notifyDataSetChanged (). Ici, vous n'utilisez pas les transactions, mais autrement vous le faites].

  1. Utiliser Fragment.instancier() pour initialiser vos fragments au lieu de constructeur.
  2. utiliser les écouteurs pour mettre à jour/supprimer la référence de l'instance (de la collection utilisée pour les référencer) de fragment onreateview et onDestroy.
  3. utilisez getView () pour obtenir la vue racine de fragment à chaque endroit et lors de la mise à jour fonctionnalité.
  4. ne pas tenir compte des instances, en fait éviter les pointeurs statiques où jamais possible.
  5. utiliser getSupportFragment au lieu de garder la référence de FragmentManager en vue de radiomessagerie adaptateur ou ailleurs.
  6. utiliser le dételage d'attaches sur la vue de cache de transaction, pour se débarrasser des vues de l'enfant sur Vue de la racine du Fragment et réinitialiser. C'est parce qu'un seul fragment doit être visible à la fois, les autres doivent se détacher. Par conséquent re-attacher sur demande.
  7. getActivity() ou getApplicationContext () le cas échéant, au lieu de conserver une variable globale pour garder les références au contexte.
  8. onConfiguration changement d'orientation, le clavier, la redimensionner): faire de l'activité et de la transmettre au fragment actif qui le gère. Important: si vous voulez utiliser des fragments pour des transactions, ne le faites pas de les déclarer dans les mises en page. Fournir l'id du conteneur (layout) dans la transaction add fragment.
  9. une transaction de Fragment doit être effectuée dans un appel d'événement, pas n'importe où ailleurs, et un tel événement ne doit pas être répétitif. Cela empêche L'Exception D'argumentation illégale.
  10. il y a une méthode ViewPager où vous n'avez pas à utiliser de Fragments.Plutôt, vous pouvez utiliser des vues, ou des groupes de vues. Cela remplace la nidification des fragments.
  11. détecter le niveau de fragments, cela signifie que si vous voulez un fragment " B "Pour remplacer le fragment existant "A", et quand vous voulez revenir pour montrer le fragment " A "en appuyant sur "B", mettez cette transaction dans la pile arrière.

astuce: attention lors de l'ajout d'une fonction de balayage car il y a d'autres vues cliquables. Glisser avec intercept touch sur RootView en retournant les touches false mais analyzing.


un de plus chose: vous devriez observer qu'avoir un fragment dans un conteneur à la fois résout un autre problème: S'il y a deux fragments , un sur le dessus de l'autre, les clics d'un fragment va à l'autre fragment qui est en dessous. Donc, masquez ou remplacez pour n'avoir qu'un fragment à la fois. Back-Stack aide à maintenir les niveaux de navigation, et sur le changement de configuration ou la mise à jour, essayer de mettre à jour la même instance du fragment actif cible, au lieu de faire des transactions parce que cela change l'ordre des fragments navigué.

1
répondu Abhinav Saxena 2014-05-30 14:32:18