Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webview doesn't fillMaxSize with pullToRefresh #10

Open
ColtonIdle opened this issue Apr 16, 2024 · 1 comment
Open

Webview doesn't fillMaxSize with pullToRefresh #10

ColtonIdle opened this issue Apr 16, 2024 · 1 comment

Comments

@ColtonIdle
Copy link

I know we talked about this on the previous issue, but I figured I'd open it so that others using the library know that this is an open issue. But essentially any webpage that should open full screen with centered content won't work with the webview.

i.e. val initialUrl = "https://www.thelinehotel.com/wp-admin"

leads to a UI that looks like this

CleanShot 2024-04-16 at 10 34 23@2x

even though in a browser does take up the full screen
CleanShot 2024-04-16 at 10 35 24@2x

This seems to be a known issue with the original accompanist webview

See: https://stackoverflow.com/questions/75751943/implement-pullrefresh-on-top-of-webview-accompanist-in-compose

For web pages that are longer than the screen it works like a charm. But for shorter pages I couldn't get them to work in fullscreen yet.

The only solution is seemingly to do the pull to refresh in using AndroidView as well, see https://stackoverflow.com/a/78096034/1048909

Ben Trengrove from google basically said here that they won't work on this google/accompanist#1670

I asked Ben about this ~last week and he said

~Probably an issue having to do with nested scrolling but would take a bit to work out

So it seems like it has something to do with nested scrolling support. Since this is the "spiritual successor" to accompanist webview, I think it would be cool to have a webview in compose that can support pull to refresh like You can do in the View System. If I try to do webview + pull to refresh in the view system you can see that it works as expected.

CleanShot 2024-04-16 at 10 41 00@2x

@Tiarait
Copy link

Tiarait commented Oct 18, 2024

Its problem webview, not lib.
I went the other way.
created a WebView where I made the ability to disable scroll setScrollDisable (to disable scrolling and selecting).
If isScrollDisabled - need return true in override fun overScrollBy.
Then added to the current compose WebView setOnTouchListener

var startY = 0f
var deltaY = 0f
wv.setOnTouchListener { _, event ->
    when (event.action) {
        MotionEvent.ACTION_DOWN -> {
            startY = event.y
            deltaY = 0f
            targetSnap = 0f
        }
        MotionEvent.ACTION_MOVE -> {
            if (webView.isAtTop && webView.isScrollDisabled) {
                val currentY = event.y
                if (startY == 0f || deltaY == 0f) startY = currentY
                val nDeltaY = if (deltaY == 0f) 0.1f else currentY - startY
                val isDirectionDown = nDeltaY > deltaY

                if (!isDirectionDown && s.distanceFraction <= 0f) {
                    webView.setScrollDisable(false)
                    startY = 0f
                    deltaY = 0f
                    return@setOnTouchListener webView.onTouchEvent(event)
                }

                deltaY = nDeltaY
                if (s.distanceFraction < 2.5f || !isDirectionDown) {
                    val target = deltaY / hPx * 10
                    if (target < 2.5f) {
                        targetSnap = target
                    }
                }
            }
        }
        MotionEvent.ACTION_UP -> {
            startY = 0f
            wv.postDelayed({
                webView.setScrollDisable(false)
            }, 500)
            if (s.distanceFraction > 1.8f) {
                targetSnap = 2f
                refresh()
            } else {
                targetSnap = 0f
            }
        }
    }
    webView.onTouchEvent(event)
}

and already there I control targetSnap (via the finger movement distance), and then I use the standard indicator


val s = rememberPullToRefreshState()
fun snapTo(targetSnap: Float, delay: Long = 0) = refreshScope.launch {
    if (delay > 0) delay(delay)
    s.snapTo(targetSnap)
}
var targetSnap by remember { mutableStateOf(0f) }
val animatedProgress by animateFloatAsState(
    targetValue = targetSnap, label = "SmoothRefresh"
)
snapTo(animatedProgress)

.....

PullToRefreshDefaults.Indicator(
    state = s,
    isRefreshing = refreshing,
    containerColor = MaterialTheme.colorScheme.onPrimary,
    color = MaterialTheme.colorScheme.tertiary)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants