ユーザーがハイパーリンクではなくウェブビューをクリックしたときを知りたい。そのクリックで、ウェブビューを保持しているアクティビティのビューを表示/非表示にします。なにか提案を?
これを見てみると、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;
}
}
お役に立てれば。
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;
}
});
Hamidrezaのソリューション 私にとってはほとんど機能しました。
実験から、単純なタップには通常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;
}
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;
}
});
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;
}
これは私のために働く
webView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// Do what you want
return false;
}
});
WebViewClient.shouldOverrideUrlLoading
は役に立つかもしれません。アプリの1つでも同様の要件があります。まだ試していません。
これは、ボタンではなくWebビューに関連付けられているためです。実装後も同じ問題が発生しました。ボタンは影響しませんでしたが、Webビューのページは影響しました。