如何在android中的webview上获得onclick事件?

时间:2011-02-25 11:54:16

标签: android android-webview

我想知道用户何时点击了网页视图而不是超链接。在该单击时,我想显示/隐藏包含webview的活动视图。有什么建议吗?

9 个答案:

答案 0 :(得分:81)

我看了一下,发现WebView似乎没有向OnClickListener发送点击事件。如果那里的任何人可以证明我错了或告诉我为什么然后我有兴趣听到它。

我找到的是WebView会将触摸事件发送到OnTouchListener。它确实有自己的onTouchEvent方法,但我似乎只是使用该方法获得MotionEvent.ACTION_MOVE

因此,我们可以在注册的触摸事件监听器上获取事件,唯一的问题是如何在用户单击URL时绕过您想要执行的任何操作。

通过发送延迟的触摸消息然后删除触摸消息,如果触摸是由用户点击URL引起的,可以通过一些花哨的Handler步法来实现。

以下是一个例子:

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;
}
}


希望这会有所帮助。

答案 1 :(得分:33)

您可以通过OnTouchListener实现OnClickListener:

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;
        }
    });

答案 2 :(得分:9)

Hamidreza's solution几乎为我工作。

我从实验中注意到,简单的点击通常有2-5个动作移动事件。检查操作向下和向上之间的时间比较简单,表现得更像我的期望。

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;
    }

答案 3 :(得分:7)

On Click事件on webView在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;                 
  }                       
});

答案 4 :(得分:4)

我认为你也可以使用MotionEvent.ACTION_UP状态,例如:

@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;
}

答案 5 :(得分:3)

这对我有用

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

答案 6 :(得分:1)

我几乎尝试了所有答案,其中一些几乎对我有用,但是这些答案都无法完美地发挥作用。所以这是我的解决方案。对于此解决方案,您将需要在HTML正文标记中添加constexpr属性。因此,如果您无法修改HTML文件,那么该解决方案将对您不起作用。

步骤1: 在HTML正文标记中添加onclick属性,如下所示:

onclick

步骤2: 在您的应用中实现<body onclick="ok.performClick(this.value);"> <h1>This is heading 1</h1> <p>This is para 1</p> </body> 以处理点击监听器:

addJavascriptInterface

步骤3: 我们无法通过webView.addJavascriptInterface(new Object() { @JavascriptInterface public void performClick(String string) { handler.sendEmptyMessageDelayed(CLICK_ON_WEBVIEW, 0); } }, "ok"); 方法对主线程执行任何操作,因此需要添加performClick类:

Handler

对您的课程实施private final Handler handler = new Handler(this); // class-level variable private static final int CLICK_ON_WEBVIEW = 1; // class-level variable ,并覆盖Handler.Callback

handleMessage

答案 7 :(得分:0)

WebViewClient.shouldOverrideUrlLoading可能会有所帮助。我们的应用程序中有一个类似的要求。尚未尝试过。

答案 8 :(得分:0)

这是因为它与网络视图绑定而不是按钮。实施后我遇到了同样的问题。该按钮没有任何影响,但网页视图中的页面确实如此。