Giới thiệu
Bài viết này minh họa cách vô hiệu hóa cuộn (scroll) trong WebView bằng cách gán OnTouchListener và trả về true cho sự kiện ACTION_MOVE. Cách này "ăn" sự kiện chạm, ngăn WebView xử lý cuộn.
Các bước thực hiện
Bước 1: Tạo dự án mới
Mở Android Studio, chọn File → New Project và tạo dự án.
Bước 2: Thiết kế giao diện (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Bước 3: Viết code logic (src/MainActivity.java)
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webView);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("https://www.youtube.com");
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
// VÔ HIỆU HÓA CUỘN
webView.setOnTouchListener((v, event) -> {
// Trả về true cho ACTION_MOVE để "ăn" sự kiện cuộn
return event.getAction() == MotionEvent.ACTION_MOVE;
});
}
@Override
public void onBackPressed() {
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
}
Bước 4: Cấu hình quyền trong AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.com.sample">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Chạy ứng dụng
Kết nối thiết bị, nhấn Run. WebView tải YouTube nhưng không thể cuộn trang bằng tay (cuộn bị chặn). Phím Back vẫn hoạt động để quay lại trang trước trong WebView.
Giải thích cơ chế
OnTouchListenerđược gọi trước khi WebView xử lý touch- Trả về
true= đã xử lý, không truyền tiếp cho WebView - Chỉ chặn
ACTION_MOVE(cuộn), vẫn cho phépACTION_DOWN,ACTION_UP(click link, nút...)
Các cách khác kiểm soát cuộn WebView
1. Vô hiệu hóa hoàn toàn (kể cả click):
webView.setOnTouchListener((v, event) -> true);
2. Chỉ cho phép cuộn dọc/ngang (XML):
<WebView
android:verticalScrollbarPosition="defaultPosition"
android:overScrollMode="never" />
3. JavaScript injection (cho web nội bộ):
webView.loadUrl("javascript:document.body.style.overflow='hidden';");
4. Custom WebView override onTouchEvent:
public class NonScrollableWebView extends WebView {
private boolean scrollEnabled = false;
public void setScrollEnabled(boolean enabled) { scrollEnabled = enabled; }
@Override public boolean onTouchEvent(MotionEvent ev) {
return scrollEnabled ? super.onTouchEvent(ev) : (ev.getAction() == MotionEvent.ACTION_MOVE);
}
}
Lưu ý
- Cách này chỉ chặn cuộn bằng touch, không ảnh hưởng đến
scrollTo(),scrollBy()bằng code - Có thể gây trải nghiệm UX kém nếu người dùng cần đọc nội dung dài
- Nên cân nhắc dùng
NestedScrollViewbao ngoài WebView nếu muốn kiểm soát cuộn toàn trang