MotionEvent de manutention dans le ScrollView dans Android
J'ai été à essayer de comprendre le comportement de MotionEvents dans ScrollViews dans Android et il y a quelque chose que je ne peux pas comprendre.
Comme un exemple j'ai fait une Activité qui a une ScrollView l'intérieur et de la ScrollView a un LinearLayout à l'intérieur. J'ai mis en place mes propres classes pour avoir le contrôle sur la touche des fonctions liées à l':
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyInnerLayout inner = new MyInnerLayout(getApplicationContext());
MyLayout layout = new MyLayout(getApplicationContext());
layout.addView(inner,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
setContentView(layout);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i("scrollview","activity dispatchTouchEvent "+ev.getAction());
return super.dispatchTouchEvent(ev);
};
@Override
public boolean onTouchEvent(MotionEvent ev) {
Log.i("scrollview","activity on touch "+ev.getAction());
return super.onTouchEvent(ev);
}
public class MyLayout extends ScrollView {
public MyLayout(Context context) {
super(context);
}
@Override
public boolean dispatchKeyEvent(KeyEvent ev) {
Log.i("scrollview","layout dispatchKeyEvent "+ev.getAction());
return super.dispatchKeyEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.i("scrollview","layout onInterceptTouchEvent "+ev.getAction());
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
Log.i("scrollview","layout on touch "+ev.getAction());
return false;
}
}
public class MyInnerLayout extends LinearLayout{
public MyInnerLayout(Context context) {
super(context);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i("scrollview","inner layout dispatchTouchEvent "+ev.getAction());
return true;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.i("scrollview","inner layout onInterceptTouchEvent "+ev.getAction());
return true;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
Log.i("scrollview","inner layout on touch "+ev.getAction());
return true;
}
}
}
Quand je clique n'importe où sur l'écran-je obtenir ce journal:
10-14 18:11:48.631: I/scrollview(14906): activity dispatchTouchEvent 0
10-14 18:11:48.631: I/scrollview(14906): layout onInterceptTouchEvent 0
10-14 18:11:48.631: I/scrollview(14906): layout on touch 0
10-14 18:11:48.631: I/scrollview(14906): activity on touch 0
10-14 18:11:48.647: I/scrollview(14906): activity dispatchTouchEvent 1
10-14 18:11:48.647: I/scrollview(14906): activity on touch 1
qui signifie que l'événement de touche n'a pas fait le chemin vers le bas à l'intérieur de la mise en page à l'intérieur de la scrollview.
cependant lorsque je change la ScrollView à un LinearLayout (il suffit juste de le changer dans le prolonge), l'événement se poursuit jusqu'à la maquette intérieure:
10-14 18:24:08.975: I/scrollview(15115): activity dispatchTouchEvent 0
10-14 18:24:08.975: I/scrollview(15115): layout onInterceptTouchEvent 0
10-14 18:24:08.975: I/scrollview(15115): inner layout dispatchTouchEvent 0
10-14 18:24:09.045: I/scrollview(15115): activity dispatchTouchEvent 1
10-14 18:24:09.045: I/scrollview(15115): layout onInterceptTouchEvent 1
10-14 18:24:09.045: I/scrollview(15115): inner layout dispatchTouchEvent 1
J'ai regardé dans le code source de la ScrollView classe et la seule touche méthodes liées qu'il remplace sont ceux que je surdéfini moi-même. Donc je ne comprends pas ce qui fait la différence entre le comportement de l'LinearLayout et la ScrollView.
OriginalL'auteur Rotem | 2012-10-14
Vous devez vous connecter pour publier un commentaire.
Peut-être que vous avez déjà compris pourquoi le comportement ci-dessus, mais juste au cas où vous ne le faites pas, voilà la raison.
Aperçu
La
onInterceptTouchEvent()
sont appelés de haut en bas (de la mère à l'enfant) permettant une vue d'intercepter le mouvement avant d'être manipulé par un enfant.La
onTouchEvent()
sont appelé bas-dessus (de l'enfant à parent) jusqu'à ce que l'un d'entre eux consomm et le cycle terminera.Un
ScrollView
intercepteMotionEvent
vérifier si elle doit faire défiler la vue avant de les transmettre à l'enfant. Si le défilement doivent être effectuées à l', l'événement est consommée et la vue enfant ne voit rien.Dans le cas de
LinearLayout
, il n'y a aucune raison pour laquelle l'événement doit être consommé au cours deonInterceptTouchEvent()
, et est toujours passé à la vue enfant.Ce qui se passe dans votre code
Parce que
MyInnerLayout
est vide, laScrollView
est toujours la consommation de laMotionEvent
.Si, par exemple, vous définissez la mise en page intérieure backgound comme ceci:
vous verrez que si vous appuyez sur l'arrière-plan de l'image de l'événement permettra d'atteindre l'enfant. Si vous appuyez à l'extérieur de l'image d'arrière-plan, l'événement sera consommée par le
ScrollView
.Espère que cette aide.
Ce qui concerne.
La meilleure explication que j'ai jamais lu sur onInterceptTouchEvent() et onTouchEvent(). Merci beaucoup!
OriginalL'auteur Luis
J'ai vues avec des animations de défilement de la vue. Animations strat et arrêter égale de mouvement (HAUT et BAS). J'ai corrigé la même solution:
}
OriginalL'auteur Sergey Sheleg