web-dev-qa-db-fra.com

La méthode onTouchEvent n'est pas appelée

J'ai un problème avec ma méthode

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

n'est jamais appelé. Des idées pourquoi en est-il ainsi? Je crée une application Google 4.0.3 API et j'essaie d'activer les balayages pour mon ViewFliper. Cependant, cela ne peut pas fonctionner car le toucher n'est jamais appelé.

Code:

 public class MainActivity extends SherlockMapActivity implements ActionBar.TabListener {

C'est la déclaration de mon activité. et pour détecter les balayages, j'ai mis en œuvre cela:

    SimpleOnGestureListener simpleOnGestureListener = new SimpleOnGestureListener(){

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

        float sensitvity = 50;
        if((e1.getX() - e2.getX()) > sensitvity){
            SwipeLeft();
        }else if((e2.getX() - e1.getX()) > sensitvity){
            SwipeRight();
        }

        return true;
    }

};
GestureDetector gestureDetector= new GestureDetector(simpleOnGestureListener);

Merci.

modifier:

main.xml:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/main_view"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:orientation="horizontal" >

<ViewFlipper
    Android:id="@+id/ViewFlipper"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:background="#ffffff" >

    <include
        Android:layout_height="match_parent"
        layout="@layout/mymain" />

    <include layout="@layout/secondmain" />
    <include layout="@layout/thirdmain" />
    <include layout="@layout/fourthmain" />
</ViewFlipper>
</LinearLayout>

Edit2: toutes mes mises en page incluses ont implémenté scrollview. Est-il possible que le défilement prenne ces événements et les gère? Et comment détecter les gestes si oui?

31
gabrjan

J'ai trouvé une solution parfaite. J'ai implémenté une nouvelle méthode:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

    View v = getCurrentFocus();
    boolean ret = super.dispatchTouchEvent(event);

et maintenant tout fonctionne bien!

Éditer:

Mon code final:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    View v = getCurrentFocus();
    if (v instanceof EditText) {
        View w = getCurrentFocus();
        int scrcoords[] = new int[2];
        w.getLocationOnScreen(scrcoords);
        float x = event.getRawX() + w.getLeft() - scrcoords[0];
        float y = event.getRawY() + w.getTop() - scrcoords[1];
        if (event.getAction() == MotionEvent.ACTION_UP
                && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w
                        .getBottom())) {

            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getWindow().getCurrentFocus()
                    .getWindowToken(), 0);
        }
    }
    boolean ret = super.dispatchTouchEvent(event);
    return ret;
}
44
gabrjan

Comme j'ai écrit dans les commentaires de la publication de Gabrjan que cela se déclenche en continu tout en touchant l'écran, il existe en fait un moyen facile d'obtenir uniquement les événements de toucher du sol:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        System.out.println("TOUCH DOWN!");
        //set immersive mode here, or whatever...
    }
    return super.dispatchTouchEvent(event);
} 

Cela m'a été très utile pour mettre le Android en mode immersif chaque fois qu'une partie de l'écran était touchée quel que soit l'élément. Mais je ne souhaitais pas définir le mode immersif à plusieurs reprises!

12
Logic1

ok, maintenant je suis sûr que le problème est que la poignée scrollview touche, donc de toute façon ignorer cela et pourtant être le défilement disponible?

Oui, c'est le problème, lorsque Android gère les événements tactiles, chaque événement passe de l'enfant au parent, donc il est d'abord géré par ViewFlipper, mais ensuite il passe à ScrollView. Vous devez donc implémenter getParent (). requestDisallowInterceptTouchEvent (true) (voir classe ViewParent ) afin que tous les événements tactiles soient traités par ViewFlipper, puis détectez simplement la direction du geste si horizontal puis inversez la vue sinon, passez l'événement tactile à ScrollView ou simplement scroll ScrollView par programmation

EDIT: Vous pouvez également implémenter OnTouchListener dans votre ViewFlipper et dans cet écouteur déclencher GestureDetector.onTouchEvent (événement), mais cela nécessite également requestDisallowInterceptTouchEvent de votre vue parent définie sur true

5
Chaosit

Tous les gestes et les événements tactiles vont à l'élément le plus bas de la hiérarchie de vue qui peut le gérer. Donc, si vous avez un auditeur dans la mise en page incluse, vous pouvez appeler ((TypeOfParrent)yourView.getParent()).onTouchEvent(event) pour déléguer l'événement au gestionnaire de votre choix.

AJOUTER: Je vous recommande d'utiliser ViewPager pour inverser les vues. Dans le ViewPager, vous n'avez pas besoin d'implémenter votre propre onGestureListener.

http://www.edumobile.org/Android/android-beginner-tutorials/view-pager-example-in-Android-development/

http://developer.Android.com/reference/Android/support/v4/view/ViewPager.html

2
Roman Nazarevych