-
Notifications
You must be signed in to change notification settings - Fork 0
Lab 18
Nate Ebel edited this page Jul 19, 2022
·
3 revisions
Integrate the Twitter PWA into the app as an alternative to using Implicit Intents.
-
Review existing use of
Intent
to launch Twitter- Notice that this takes user to another app to carry out the action
-
Load Twitter's PWA using a
WebView
- Add a
WebView
toactivity_twitter.xml
- Enable Javascript on the
WebView
- Call
WebView.loadUrl()
with"https://mobile.twitter.com"
. Can use the given utility method by callingbinding.webView.loadTwitter()
.
- Add a
-
Load Twitter's PWA directly into the "Composer"
- Replace the loading of
"https://mobile.twitter.com"
with"https://mobile.twitter.com/intent/tweet?hashtags=$csvFormattedHashtags"
by callingbinding.webView.loadTwitterComposer()
- Replace the loading of
-
Display a native
ProgressBar
when PWA is loading- Create a
ProgressChromeClient
class that extendsWebChromeClient
- Update the constructor to take a single
ProgressBar
property - Within
onProgressChanged()
show theProgressBar
any time the current progress is between 1-99 - Set an instance of
ProgressChromeClient
as thewebChromeClient
on theWebView
- Re-launch your
TwitterActivity
to observe your nativeProgressBar
being updated in response to loading of the PWA
- Create a
-
Display yor own simple web app that bridges between Javascript and Kotlin
- Review the class
SimpleWebAppInterface
- Review
WebView.loadSimpleWebApp(activity: Activity)
withinWebViewContentExtensions.kt
- Invoke
loadSimpleWebApp()
fromTwitterActivity.onCreate()
- Re-launch your
TwitterActivity
to observe that actions taken from the Javascript are responded to natively in Kotlin code
- Review the class
- Add additional styling/actions to the HTML defined in
loadSimpleWebApp()
and respond natively - Add a
FloatingActionButton
that is drawn over your custom HTML/Javascript and that launches the Twitter PWA when clicked- This demonstrates the mixing of native controls with web content for a hybrid approach
- Android WebView Guide
- Enabling Javascript in a WebView
- Connecting Javascript to Kotlin
- Android WebView Docs
- How we built Twitter Lite
fun WebView.loadTwitter() {
loadUrl("https://mobile.twitter.com")
}
/**
* Will load Twitter's PWA "Twitter Lite" and open up to the composer with a set of pre-populated
* hashtags
*/
fun WebView.loadTwitterComposer(vararg hashtags: String) {
val formattedHashtags = hashtags.toList().reduceRightIndexed { index, s, acc ->
val separator = if(index == hashtags.size -1) "" else ","
acc + separator + s
}
loadUrl("https://mobile.twitter.com/intent/tweet?hashtags=$formattedHashtags")
}
Look no further!
Ensure that you've added the SimpleWebAppInterface
class to yor project.
Then, add the WebView.loadSimpleWebApp()
extension function and invoke it after setting up your WebView
in onCreate()
The created instance of SimpleWebAppInterface
will be used to connect to click handlers defined in the Javascript
/**
* Basic example of a Kotlin -> Javascript bridging implementation
*/
class SimpleWebAppInterface(private val activity: Activity) {
@JavascriptInterface
fun showToast(toast: String) {
Toast.makeText(activity, toast, Toast.LENGTH_SHORT).show()
}
@JavascriptInterface
fun navigateBack() {
activity.finish()
}
}
/**
* Will load some basic html/javascript with a bridging class to communicate back to the Activity
*/
fun WebView.loadSimpleWebApp(activity: Activity) {
addJavascriptInterface(SimpleWebAppInterface(activity), "SimpleWebAppInterface")
val html = """
<!DOCTYPE html>
<html>
<head>
<style>
body {background-color: powderblue;}
h1 {color: blue;}
p {color: red;}
</style>
</head>
<body>
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<input type="button" value="Finish" onClick="navigateBack()" />
<h1>Simple Web App</h1>
<p>Connect HTML/Javascript elements to our mobile app</p>
</body>
<script type="text/javascript">
function showAndroidToast(toast) {
SimpleWebAppInterface.showToast(toast);
}
function navigateBack() {
SimpleWebAppInterface.navigateBack();
}
</script>
</html>
""".trimIndent()
val encodedHtml = Base64.encodeToString(html.toByteArray(), Base64.NO_PADDING)
loadData(encodedHtml, "text/html", "base64")
}