I am trying to show webview in foreground with floating view, i am taking webview from companion object of activity, and i added this to the floating view by removing webview' parent, and it worked and showing webview without losing current loaded page.
The problem is i wanna return this webview to the activity when user want to return to the app. And the same method (taking webview from foreground and removing parent of webview and giving this to compose AndroidView widget) not working and activity not showing webview, and it's not showing in foregroun too, if i switch to floating widget after that
The Floating View in foreground:
class OverlayWebViewScreen(
private val context: Context,
private val webView: WebView,
val lifecycleService: ForegroundComposeLifeCycle
) {
private lateinit var windowManager: WindowManager
private lateinit var layoutParams: WindowManager.LayoutParams
fun open() {
PermissionManager.askForDisplayOverApps(context)
context.run {
windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
layoutParams = WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
)
val parentView = webView.parent as? ViewGroup
parentView?.removeView(webView)
val composableView = ComposeView(context)
lifecycleService.attachToDecorView(composableView)
lifecycleService.onResume()
composableView.setViewTreeLifecycleOwner(lifecycleService)
composableView.setContent {
var offsetX by remember { mutableFloatStateOf(0f) }
var offsetY by remember { mutableFloatStateOf(0f) }
Column(modifier = Modifier.size(300.dp))
{
Row {
Icon(
modifier = Modifier
.background(color = Color.Magenta)
.pointerInput(Unit) {
detectDragGestures { change, dragAmount ->
offsetX += dragAmount.x
offsetY -= dragAmount.y
layoutParams.x = offsetX.toInt()
layoutParams.y = offsetY.toInt()
windowManager.updateViewLayout(composableView, layoutParams)
}
},
imageVector = Icons.Default.DragHandle, contentDescription = null
)
IconButton(onClick = {
windowManager.removeView(composableView)
ServiceManager.restartActivityWhenKilled(context)
}) {
Icon(
modifier = Modifier
.background(color = Color.Magenta)
,
imageVector = Icons.Default.OpenInFull, contentDescription = null
)
}
}
AndroidView(
modifier = Modifier.size(200.dp),
factory = {
webView
}
)
AdsManager.BannerAdView(modifier = Modifier)
}
}
// Set the position of the WebView at the bottom of the screen
layoutParams.gravity = Gravity.BOTTOM or Gravity.START
windowManager.addView(composableView,layoutParams)
}
}
fun close(){
ServiceManager.restartActivityWhenKilled(context)
}
}
Activity's onStart Method which is Compose and where i am getting webview from foreground service
override fun onStart() {
val backPressedCallback = onBackPressedCallbackOverride()
logger("onStart")
if (ServiceManager.isServiceActive()){
val parentView = webView.parent as? ViewGroup
parentView?.removeView(webView)
webView = AutoRefreshService.getWebView()
webViewChanged.value = webViewChanged.value.not()
logger(webView.toString())
}
setContent {
val context = LocalContext.current
val activity = context as? ComponentActivity
activity?.onBackPressedDispatcher?.addCallback(this, backPressedCallback)
InitVariables()
AutoRefreshWebPageTheme {
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
Scaffold(
modifier = Modifier.fillMaxSize(),
) { paddingValues ->
Column(modifier = Modifier.padding(paddingValues)) {
AndroidView(
modifier = Modifier.weight(1f),
update = {
if (webViewChanged.value)
webView.bringToFront()
},
factory = { webView },
)
AdsManager.BannerAdView(modifier = Modifier)
}
}
if (autoRefreshDialog.value) {
AutoRefreshDialog()
}
}
}
}
if (preferences.getAutoRefreshStatus()){
if (ServiceManager.isServiceActive().not()) {
startPageReloading(this)
}
}
super.onStart()
}
I tried compainion object in order to share webview across app, it taking just 200mb in ram in profiler. and I took webview from activity and applied to foreground and it showed webview with loaded screen even. But the reverse method (taking webview from foreground to the activity not working) video: here is situation
My expectation is returning to the activity by loaded screen of webview
I found the solution after couple of trying: Solution is i didn't attached webview to the androidView in jetpack compose because i had no idea how to do, but i found:
Attaching to the AndroidView parent group will be like that:
lateinit var webViewGroup: ViewGroup
...
AndroidView(
modifier = Modifier.weight(1f),
update = { view ->
val viewGroup = view.parent as? ViewGroup
viewGroup?.let {
// I used webViewGroup variable to keep view's parent in case it's
//changed unexpectedly
if (::webViewGroup.isInitialized.not()){
webViewGroup = viewGroup
// removing webview's current parent and attach to activity's
//parent
val parentView = webView.parent as? ViewGroup
parentView?.removeView(webView)
webViewGroup.addView(webView)
}
}
},
factory = { webView },