Mobile Apps 2023W Lecture 21
Revision as of 23:26, 29 March 2023 by Soma (talk | contribs) (Created page with "==Notes== <pre> March 29 -------- So I'm trying to figure out how to implement the back button properly. Currently, the back button gets triggered but doesn't work right, .goBack() isn't doing what we expected - hypothesis: state changes are updating history too often, getting copies of current page and so can't keep track of last page properly Two choices: - integrate more tightly with webview history so we can better manipulate and interact with it - ignore webv...")
Notes
March 29 -------- So I'm trying to figure out how to implement the back button properly. Currently, the back button gets triggered but doesn't work right, .goBack() isn't doing what we expected - hypothesis: state changes are updating history too often, getting copies of current page and so can't keep track of last page properly Two choices: - integrate more tightly with webview history so we can better manipulate and interact with it - ignore webview history, implement it all on our own and just push current page to the webview widget as needed
Code
package carleton.comp2601.webviewcompose
import android.os.Bundle
import android.util.Log
import android.view.ViewGroup
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.viewinterop.AndroidView
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
// Calling the composable function
// to display element and its contents
MainContent()
}
}
}
// Creating a composable
// function to display Top Bar
@Composable
fun MainContent() {
var curURL by remember { mutableStateOf("https://news.ycombinator.com") }
var navigate by remember { mutableStateOf("") }
Scaffold(
// topBar = { TopAppBar(title = {Text("COMP 2601")})},
topBar = {
Row {
ClickableText(
AnnotatedString(text = "Back"),
onClick = {
navigate = "back"
Log.d("webviewCompose", "navigate = back")
}
)
URLBar(curURL = curURL, updateURL = { curURL = it })
}
},
content = { MyContent(curURL = curURL, updateURL = {
curURL = it
Log.d("webviewCompose", "updating URL to $curURL")
},
navigate = navigate, resetNavigate = { navigate = ""}) }
)
}
@Composable
fun URLBar(curURL: String, updateURL: (String) -> Unit) {
var newURL = ""
TextField(
value = curURL,
//onFocusChange = { updateURL(newURL) },
//onValueChange = { updatedURL: String -> newURL = updatedURL},
onValueChange = updateURL,
label = { Text("Enter URL here") }
)
}
@Composable
fun MyContent(curURL: String, updateURL: (String) -> Unit,
navigate: String, resetNavigate: () -> Unit){
class ObservableWebViewClient : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
if (url != null) {
updateURL(url)
}
return false
}
}
fun logWebViewHistory(view: WebView) {
val history = view.copyBackForwardList()
val current = history.currentIndex
Log.d("webviewCompose", "Current history item: $current")
Log.d("webviewCompose", "Webview BackForwardList contents:")
for (i in 0..history.size -1) {
val item = history.getItemAtIndex(i)
if (item != null) {
val u = item.originalUrl
Log.d("webviewCompose", " $i: $u")
}
}
}
// Adding a WebView inside AndroidView
// with layout as full screen
AndroidView(factory = {
WebView(it).apply {
// layoutParams = ViewGroup.LayoutParams(
// ViewGroup.LayoutParams.MATCH_PARENT,
// ViewGroup.LayoutParams.MATCH_PARENT
// )
webViewClient = ObservableWebViewClient()
loadUrl(curURL)
}
}, update = {
if (navigate == "back") {
Log.d("webviewCompose", "Navigating back")
val currentURL = it.url
Log.d("webviewCompose", "currentURL = $currentURL")
it.goBack()
val prevURL = it.url
Log.d("webviewCompose", "prevURL = $prevURL")
if (currentURL == prevURL) {
Log.d("webviewCompose", "current and prev are the SAME!")
}
if (prevURL != null) {
Log.d("webviewCompose", "updating URL after back button")
updateURL(prevURL)
}
resetNavigate()
logWebViewHistory(it)
} else {
Log.d("webviewCompose", "loading URL $curURL")
it.loadUrl(curURL)
logWebViewHistory(it)
}
})
}
// For displaying preview in
// the Android Studio IDE emulator
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
MainContent()
}