Comment détecter l'événement tactile si l'utilisateur touche la vue A et glisse jusqu'en bas de la vue B. Je souhaite détecter l'événement tactile dans la vue B.
J'ai ajouté un écouteur tactile dans la vue B, mais je ne recevais pas les événements si l'utilisateur avait initialement touché A et fait glisser le B.
Vous pouvez utiliser le code ci-dessous pour répondre à votre demande:
Méthode de test des limites de la vue (utilisée dans le code ci-dessous)
Rect outRect = new Rect();
int[] location = new int[2];
private boolean isViewInBounds(View view, int x, int y){
view.getDrawingRect(outRect);
view.getLocationOnScreen(location);
outRect.offset(location[0], location[1]);
return outRect.contains(x, y);
}
Test avec deux TextView
final TextView viewA = (TextView) findViewById(R.id.textView);
final TextView viewB = (TextView) findViewById(R.id.textView2);
Vue de configurationA
La OnClickListener
vide est nécessaire pour garder OnTouchListener
active jusqu'au ACTION_UP
viewA.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {}
});
viewA.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int)event.getRawX();
int y = (int)event.getRawY();
if(event.getAction() == MotionEvent.ACTION_UP){
if(isViewInBounds(viewB, x, y))
viewB.dispatchTouchEvent(event);
else if(isViewInBounds(viewA, x, y)){
Log.d(TAG, "onTouch ViewA");
//Here goes code to execute on onTouch ViewA
}
}
// Further touch is not handled
return false;
}
});
Vue de configurationB
Cela n’est nécessaire que si vous souhaitez également appuyer sur viewB et faire glisser pour afficherA
viewB.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {}
});
viewB.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int)event.getRawX();
int y = (int)event.getRawY();
if(event.getAction() == MotionEvent.ACTION_UP){
if(isViewInBounds(viewA, x, y))
viewA.dispatchTouchEvent(event);
else if(isViewInBounds(viewB, x, y)){
Log.d(TAG, "onTouch ViewB");
//Here goes code to execute on onTouch ViewB
}
}
// Further touch is not handled
return false;
}
});
Cordialement.
Dans View
A, écrasez onTouchEvent
comme suit:
@Override
public boolean onTouchEvent(MotionEvent event)
{
float x = event.getRawX();
float y = event.getRawY();
if ( (B.getLeft() <= x <= B.getRight()) &&
(B.getTop() <= y <= B.getBottom())
)
{
Log.i("A", "Motion Event is currently above B");
B.dispatchTouchEvent(event);
}
return true;
}
Dans View
B, remplacez la même méthode, en vous assurant que vous retournez false:
@Override
public boolean onTouchEvent(MotionEvent event)
{
//TODO handle touch event
return false;//this will allow A to continue using the event
}
Si vous renvoyez true de l'événement onTouchEvent de la vue A, l'événement n'est pas propagé. Dans ce cas particulier, lorsque A est inférieur à B, retourne false à partir du onTouch of view A.
Cela aiderait aussi si vous pouvez poster du code.
Je suis certain que vous devez utiliser la méthode ViewGroup.dispatchTouchEvent(MotionEvent ev)
de substitution dans votre groupe de vues, qui contient les vues A et B. L'implémentation d'origine définit la vue cible lorsque le conteneur reçoit MotionEvent.getAction() == MotionEvent.ACTION_DOWN
, puis distribue tous les événements tactiles suivants dans la vue cible jusqu'à ce qu'elle reçoive MotionEvent.getAction() == MotionEvent.ACTION_UP
ou MotionEvent.ACTION_CANCEL
.
Dans votre cas, la vue cible est A ou le conteneur lui-même (dépend de l’implémentation de votre méthode conteneur onInterceptTouchEvent(MotionEvent ev)
). Vous devez donc redéfinir ce comportement et répartir les événements tactiles non seulement vers la vue cible, mais également vers toutes les vues situées sous la zone touchée (par exemple, pour afficher B).
Si vous êtes intéressé, vous pouvez partager un exemple de code et je vais essayer de vous aider davantage.
Lorsque vous avez terminé la vue B, appelez la onTouch
manuellement.
if (viewBRect.contains(x, y)) {
viewBsonTouch(view, motionEvent);
}
Essayez d’utiliser le framework drag and drop.