Scrollview ne glisse pas quand il est trop court pour faire défiler

Je suis assez nouveau pour le développement d'applications Android, et j'ai joué avec des gestes swipe à l'aide de SimpleOnGestureListener d'Android et d'un ViewFlipper. Il y a 3 enfants de ViewFlipper, et chacun est un ScrollView. Ils sont tous dynamiquement peuplés lorsque l'activité est chargée, et ils ne changent pas après cela. The ScrollView est l'endroit où les SimpleOnGestureListeners sont attachés.

Voici la mise en page que j'utilise:
+ ViewFlipper
++ ScrollView (x3, un pour chaque page, chacun avec ce qui suit 🙂
+++ LinearLayout (vertical)
++++ TextView
++++ TableLayout (rempli dynamiquement w / TableRows)
++++ View

  • ERREUR: doit implémenter OnFragmentInteractionListener
  • Android WebView à l'intérieur de ScrollView scrolls only scrollview
  • La création AsyncTask provoque un crash
  • Fling gesture detection on grid layout
  • "Ressource introuvable" lors de la création d'une application Android sous IntelliJ 9.0 Maia Public Beta
  • MPAndroidChart masquer la grille de fond
  • J'ai étendu la méthode onFling avec le code de tutoriel commun que vous pouvez trouver n'importe où en ligne, et cela fonctionne très bien – sauf si l'une des ScrollViews ne contient pas assez de contenu pour défiler.

    J'ai limité le problème à la détection tactile en annulant et en appelant super sur toutes les méthodes de SimpleOnGestureListener pour ajouter un journal d'impression.

    Lorsque je glisse sur une page qui défile, j'obtiens quelque chose de complet dans "onClick" dans "OnScroll" "in onFling", etc. Sur une page trop courte pour faire défiler, je reçois "in onClick" "dans onShowPress" "dans OnLongPress ", Et ce n'est que si je touche le contenu dans les enfants de la défilé trop court – si je touche ailleurs, je ne reçois aucun événement.

    Des idées sur ce qui ne va pas, ou comment détecter le geste de balayage quelle que soit la taille de ScrollView?

    EDIT: J'ai déterminé que lorsque je l'exécute sur un émulateur Android 2.2, par opposition à l'émulateur Android 2.1u1 DroidX que j'ai utilisé, il disparaît. Ceci est reproductible sur plusieurs environnements.


    J'ai une idée plus approfondie de ceci; Il semble que onInterceptTouchEvent ne soit pas appelé pour chaque événement de mouvement lorsqu'un scrollview est contenu dans un flipper (ou un WorkspaceView).

    En particulier, le comportement que j'ai trouvé lors de la modification d'une autre classe de vue pour réparer ce même problème (ce n'est pas unique aux palmes) était le suivant: notez que c'est Android 2.1 uniquement:

    Si la vue de défilement est suffisamment longue pour défiler, l'événement de mouvement ACTION_DOWN est capturé par ScrollView, et tous les événements ACTION_MOVE subséquents se déroulent sur InterceptTouchEvent du flipper, où il est intercepté et manipulé de manière appropriée. Dans Android 2.2, ce comportement se produit indépendamment de la longueur de défilement.

    Retour à 2.1: si la vue de défilement n'est pas suffisamment longue pour défiler, l'événement de mouvement ACTION_DOWN n'est pas capturé par la vue de défilement, mais revient à l'événement OnTouchEvent de la flipper. Tous les événements ACTION_MOVE suivants du même geste ignorent la fonction onInceptceptTouchEvent et vont directement à la fonction onTouchEvent!

    La façon dont j'ai résolu cela était de prendre les fonctionnalités que j'avais dans les événements ONTouchEvent pour ACTION_MOVE et de la refactoriser dans sa propre méthode. De cette façon, je peux avoir onTouchEvent appelerInterceptTouchEvent suivi de cette fonctionnalité si elle détecte que l'événement a déjà été dérangé.

    case MotionEvent.ACTION_MOVE: if (touchState == TOUCH_STATE_SCROLLING) { handleScrollMove(ev); } else { // Log.d("workspace","caught a move touch event but not scrolling"); //NOTE: We will never hit this case in Android 2.2. This is to fix a 2.1 bug. //We need to do the work of interceptTouchEvent here because we don't intercept the move //on children who don't scroll. Log.d("workspace","handling move from onTouch"); if(onInterceptTouchEvent(ev) && touchState == TOUCH_STATE_SCROLLING){ handleScrollMove(ev); } } break; 

    C'est à partir de WorkspaceView.java (une modification de Workspace.java d'Android, trouvée dans le projet andro-views sur le code google, et maintenant ici: "onglet horizontal" ish défilement entre les vues ). Dans le cas où nous recevons un événement de déplacement, et nous défilons (ce qui ne se produit que si nous avons choisi délibérément de l'intercepter – c'est-à-dire qu'il est défini dans la fonction d'interception, nous avons déjà été à la fonction d'interception) Le comportement de déplacement que nous désirons. Si nous recevons un événement de déplacement ici et que nous ne défilons pas, nous envoyons l'événement à l'aide d'Interconnexion, puis voyez si nous sommes maintenant configurés pour défiler. Si tel est le cas, nous effectuons l'action.

    Ce n'est pas élégant, mais ça marche!

    2 Solutions collect form web for “Scrollview ne glisse pas quand il est trop court pour faire défiler”

    J'avais besoin de créer une nouvelle classe qui étendait ScrollView et utilisait ceci:

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

    Je ne sais pas pourquoi, mais si j'essaie de renvoyer tout ce qui est vrai dans dispatchTouchEvent (la chose logique aurait été de

     return (gestureDetector.onTouchEvent(ev) || super.dispatchTouchEvent(ev)); 

    Si je comprends bien), cela ne fonctionne pas, et cela ne fonctionne pas.

    Essayez de configurer android:fillViewport="true" dans votre mise en page xml pour chaque ScrollView s. Cela indique à ScrollView d'être aussi large que la vue dans laquelle elle se trouve.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.