I’ve wrapped a WebView
in a androidx.swiperefreshlayout.widget.SwipeRefreshLayout
:
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="false"
tools:layout_editor_absoluteX="201dp"
tools:layout_editor_absoluteY="359dp" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
It works pretty well: Pulling down far enough triggers the callback to reload the page.
However, we have elements on the page that are drag-/sortable.
Unfortunately, dragging is being interpreted as scrolling as well — and therefore also triggering the SwipeRefresh.
This is surprising to me because I just implemented the same thing in iOS with WKWebView
. While that had its own share of surprises (handling cookies…), this actually worked like I would have expected: The SwipeRefreshLayout
is coupled to actual scroll events on the page, not any touch-and-drag-event.
See this Gif as an example of the issue:
I find it very surprising that I absolutely can’t find anything about this anywhere. Surely we can’t be the first people to encounter this issue.
I even understand why it occurs conceptually. I fail to be able to come up with a good solution, though.
Also, I have no clue about Java and/or Kotlin and the Android SDK. I have extensive experience with Flutter, but I’m out of my element here.
Any help is greatly appreciated.
For completeness sake, here’s my MainActivity.kt
:
class MainActivity : AppCompatActivity() {
private var swipeRefreshLayout: SwipeRefreshLayout? = null
private lateinit var webView: WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
swipeRefreshLayout = findViewById<SwipeRefreshLayout>(R.id.swipe_layout);
swipeRefreshLayout!!.isEnabled = false;
webView = findViewById<View>(R.id.webview) as WebView
webView.settings.javaScriptEnabled = true;
webView.settings.domStorageEnabled = true;
webView.settings.setSupportMultipleWindows(true);
webView.settings.javaScriptCanOpenWindowsAutomatically = true;
webView.viewTreeObserver.addOnScrollChangedListener(OnScrollChangedListener {
val scrollY: Int = webView.scrollY
if(scrollY == 0) {
swipeRefreshLayout!!.isEnabled = true;
} else {
swipeRefreshLayout!!.isEnabled = false;
}
})
webView.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
// ...
}
}
webView.webChromeClient = object : WebChromeClient() {
override fun onCreateWindow(
view: WebView,
dialog: Boolean,
userGesture: Boolean,
resultMsg: Message
): Boolean {
// ...
}
}
initializeRefreshListener();
webView.loadUrl("http://abc123.xyz789");
}
private fun initializeRefreshListener() {
swipeRefreshLayout!!.setOnRefreshListener {
webView.loadUrl(webView.url!!);
val x = swipeRefreshLayout
if(x != null) {
if (x.isRefreshing) {
x.isRefreshing = false
}
}
}
}
}
Source: Android Questions