web-dev-qa-db-fra.com

Comment puis-je obtenir l'événement onclick sur la visualisation Web dans Android?

Je veux savoir quand l'utilisateur clique sur la vue Web mais pas sur un lien hypertexte. Sur ce clic, je souhaite afficher/masquer une vue de mon activité qui contient une vue Web. Toute suggestion?

65
Arslan Anwar

J'ai jeté un coup d'oeil à ceci et j'ai trouvé qu'un WebView ne semble pas envoyer les événements de clic à un OnClickListener. Si quelqu'un peut me prouver le contraire ou me dire pourquoi, je serais intéressé de l'entendre.

Ce que j'ai trouvé, c'est qu'un WebView enverra des événements tactiles à un OnTouchListener. Il a sa propre méthode onTouchEvent mais je ne semblais avoir que MotionEvent.ACTION_MOVE en utilisant cette méthode.

Donc, étant donné que nous pouvons obtenir des événements sur un écouteur d’événements tactiles enregistré, le seul problème qui reste est de savoir comment contourner l’action que vous souhaitez effectuer lorsque vous cliquez sur une URL.

Ceci peut être réalisé avec un jeu de jambes fantaisie Handler en envoyant un message différé au contact, puis en supprimant ces messages au toucher si le contact a été provoqué par le fait que l'utilisateur a cliqué sur une URL.

Voici un exemple:

public class WebViewClicker extends Activity implements OnTouchListener, Handler.Callback {

private static final int CLICK_ON_WEBVIEW = 1;
private static final int CLICK_ON_URL = 2;

private final Handler handler = new Handler(this);

private WebView webView;
private WebViewClient client;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.web_view_clicker);

    webView = (WebView)findViewById(R.id.web);
    webView.setOnTouchListener(this);

    client = new WebViewClient(){ 
        @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { 
            handler.sendEmptyMessage(CLICK_ON_URL);
            return false;
        } 
    }; 

    webView.setWebViewClient(client);
    webView.setVerticalScrollBarEnabled(false);
    webView.loadUrl("http://www.example.com");
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    if (v.getId() == R.id.web && event.getAction() == MotionEvent.ACTION_DOWN){
        handler.sendEmptyMessageDelayed(CLICK_ON_WEBVIEW, 500);
    }
    return false;
}

@Override
public boolean handleMessage(Message msg) {
    if (msg.what == CLICK_ON_URL){
        handler.removeMessages(CLICK_ON_WEBVIEW);
        return true;
    }
    if (msg.what == CLICK_ON_WEBVIEW){
        Toast.makeText(this, "WebView clicked", Toast.LENGTH_SHORT).show();
        return true;
    }
    return false;
}
}


J'espère que cela t'aides.

82
Louth

Vous pouvez implémenter un OnClickListener via OnTouchListener:

webView.setOnTouchListener(new View.OnTouchListener() {

        public final static int FINGER_RELEASED = 0;
        public final static int FINGER_TOUCHED = 1;
        public final static int FINGER_DRAGGING = 2;
        public final static int FINGER_UNDEFINED = 3;

        private int fingerState = FINGER_RELEASED;


        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {

            switch (motionEvent.getAction()) {

                case MotionEvent.ACTION_DOWN:
                    if (fingerState == FINGER_RELEASED) fingerState = FINGER_TOUCHED;
                    else fingerState = FINGER_UNDEFINED;
                    break;

                case MotionEvent.ACTION_UP:
                    if(fingerState != FINGER_DRAGGING) {
                        fingerState = FINGER_RELEASED;

                        // Your onClick codes

                    }
                    else if (fingerState == FINGER_DRAGGING) fingerState = FINGER_RELEASED;
                    else fingerState = FINGER_UNDEFINED;
                    break;

                case MotionEvent.ACTION_MOVE:
                    if (fingerState == FINGER_TOUCHED || fingerState == FINGER_DRAGGING) fingerState = FINGER_DRAGGING;
                    else fingerState = FINGER_UNDEFINED;
                    break;

                default:
                    fingerState = FINGER_UNDEFINED;

            }

            return false;
        }
    });
34

solution de Hamidreza a presque fonctionné pour moi.

J'ai remarqué par expérimentation qu'un simple tapement a généralement 2 à 5 événements de mouvements d'action. Vérifier le temps entre l'action bas et haut était plus simple et se comportait plutôt comme ce à quoi je m'attendais.

private class CheckForClickTouchLister implements View.OnTouchListener {
    private final static long MAX_TOUCH_DURATION = 100;

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                m_DownTime = event.getEventTime(); //init time

                break;

            case MotionEvent.ACTION_UP:
                if(event.getEventTime() - m_DownTime <= MAX_TOUCH_DURATION)
                    //On click action

                break;

            default:
                break; //No-Op

        }
        return false;
    }
10
bduhbya

L'événement On Click On webView fonctionne comme suit avec onTouch:

imagewebViewNewsChart.setOnTouchListener(new View.OnTouchListener(){

  @Override   
  public boolean onTouch(View v, MotionEvent event) { 
    if (event.getAction()==MotionEvent.ACTION_MOVE){                        
       return false;     
    }

    if (event.getAction()==MotionEvent.ACTION_UP){    
        startActivity(new Intent(this,Example.class));                

    } 

    return false;                 
  }                       
});
7
Raza Baloch

Je pense que vous pouvez également utiliser l'état MotionEvent.ACTION_UP, par exemple:

@Override
public boolean onTouch(View v, MotionEvent event) {
    switch (v.getId()) {
    case R.id.iv:
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (isheadAndFootShow == false) {
                headLayout.setVisibility(View.VISIBLE);
                footLayout.setVisibility(View.VISIBLE);
                isheadAndFootShow = true;
            } else {
                headLayout.setVisibility(View.INVISIBLE);
                footLayout.setVisibility(View.INVISIBLE);
                isheadAndFootShow = false;
            }
            return true;
        }
        break;
    }

    return false;
}
4
wangzhengyi

Ça marche pour moi

webView.setOnTouchListener(new View.OnTouchListener() {
                            @Override
                            public boolean onTouch(View v, MotionEvent event) {
                                // Do what you want
                                return false;
                            }
                        });
2
SpyZip

WebViewClient.shouldOverrideUrlLoading pourrait être utile. Nous avons une exigence similaire dans l'une de nos applications. Pas encore essayé.

0
yogiam

C’est parce qu’il est lié à la vue Web et non au bouton. J'ai eu le même problème après la mise en œuvre. Le bouton n'a eu aucun effet, mais la page dans l'affichage Web l'a fait.

0
FranticCity