Using ForemWebView android Library - forem/ForemWebView-android GitHub Wiki

Thank for for showing interest in the library. You can setup this library in your project as mentioned her.

You can have a quick look at MainActivity.kt in this project which actually usages this library.

ForemWebView-android library is specifically designed to use forem instances in android app by using its WebViewFragment which basically loads the forem-web-instance in a WebView along with providing other interaction related features.

Using WebViewFragment to load a forem instance

Using FrameLayout in xml file.

You will need a FrameLayout in your activity/fragment's xml file. This FrameLayout will contain the [WebViewFragment].

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <FrameLayout
    android:id="@+id/web_view_fragment"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@color/black"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Adding WebViewFragment to FrameLayout

Lets just see the code first and then understand it after that:

    private fun loadOrUpdateFragment(url: String) {
        if (getWebViewFragment() == null) {
            // This result listener is used to get information about forem once the forem has been loaded.
            // The main values that it fetches are logoUrl, foremUrl and foremName.
            supportFragmentManager.setFragmentResultListener(
                WebViewConstants.FOREM_META_DATA_RESULT_LISTENER_KEY,
                /* lifecycleOwner= */ this
            ) { _, bundle ->
                // val logoUrl = bundle.getString(WebViewConstants.FOREM_META_DATA_LOGO_KEY)
                // val foremUrl = bundle.getString(WebViewConstants.FOREM_META_DATA_URL_KEY)
                val foremName = bundle.getString(WebViewConstants.FOREM_META_DATA_TITLE_KEY)
                foremNameTextView.text = foremName
            }
            // This is basically use to navigate between different web pages by getting three information
            // canGoBack, canGoForward or homeReached.
            supportFragmentManager.setFragmentResultListener(
                "WEB_VIEW_FRAGMENT_RESULT_LISTENER_KEY",
                /* lifecycleOwner= */ this
            ) { _, bundle ->
                val canGoBack = bundle.getBoolean(WebViewConstants.WEB_VIEW_CAN_GO_BACK_KEY)
                val canGoForward = bundle.getBoolean(WebViewConstants.WEB_VIEW_CAN_GO_FORWARD_KEY)
                val homeReached = bundle.getBoolean(WebViewConstants.WEB_VIEW_HOME_REACHED_KEY)

                if (homeReached) {
                    onWebPageHomeReached()
                } else {
                    // Enable these image views if you have back/forward icons in your code outside of `FrameLayout`.
                    // backImageView.isEnabled = canGoBack
                    // forwardImageView.isEnabled = canGoForward
                }
            }

            // If needsForemMetaData is false it means that it will not fetch meta data i.e. logoUrl, foremUrl and
            //  foremName and therefore the first fragment result listener won't work.
            val webViewFragment = WebViewFragment.newInstance(
                url,
                "WEB_VIEW_FRAGMENT_RESULT_LISTENER_KEY",
                needsForemMetaData = true
            )
            this.supportFragmentManager.beginTransaction().add(
                R.id.web_view_fragment,
                webViewFragment
            ).commit()
        } else {
            getWebViewFragment()?.updateForemInstance(url)
        }
    }

    private fun getWebViewFragment(): WebViewFragment? {
        return this.supportFragmentManager.findFragmentById(
            R.id.web_view_fragment
        ) as WebViewFragment?
    }
  1. In this code getWebViewFragment() function helps us to know if WebViewFragment has been attached to our FrameLayout or not.

  2. The loadOrUpdateFragment accepts a forem-instance url and loads it in WebView Fragment.

  • We use setFragmentResultListener to communicate information from WebViewFragment to its parent activity/fragment and we also listen to this information. The setFragmentResultListener can be used by adding a key in this case it is WEB_VIEW_FRAGMENT_RESULT_LISTENER_KEY and inside setFragmentResultListener we can listen to details like canGoBack which informs if the webview/website can go back to previous page, canGoForward which informs if the webview/website can go forward to previous page and homeReached is true if the website has reached its home page. All these values help us to decide what happens when the user clicks on back button in app i.e. if canGoBack is true then don't close the app instead go back to the previous page in webview.
  1. Finally the newInstance function inside WebViewFragment helps us to create a new instance of the fragment. This fragment requires three things:
  • url: the url of the forem-instance which needs to be shown in webview.
  • resultListenerKey: key required to send data back to parent activity/fragment using setFragmentResultListener.
  • needsForemMetaData: determines whether [WebView] needs to load the metadata like name, logo, etc and send it back to the parent. This needs to be true when the user has tried to add forem instance by adding a domain name (without any other information) so that we can get other information like name, logo, etc.

Other code resources

There are various functions and variables defined in library that you can use to get different information about the WebView.

  • onBackPressedFragment(): Function which gets called whenever the back button is pressed in android app to either move to previous webpage or exit the app.
  • navigateBack(): Navigates back in webview history if possible.
  • navigateForward(): Navigates forward in webview history if possible.
  • updateForemInstance(url: String): Accepts the new url of forem which needs to be loaded in webview.
  • refresh(): Refreshes the webview.
  • currentWebViewStatus: This is a MutableLiveData which reflects the current status of webview i.e. LOADING, SUCCESSFUL and FAILED. We can use this to observe the state and control the loading indicator in activity.