Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
📱 Device Features  ·  Lesson 39

WebView (Website in App)

When to use a WebView

  • Help pages, privacy policy, terms — content you already have on your website.
  • A screen that changes often and is easier to update on the server (offers, blog).
  • Hybrid apps: native navigation + some web screens (common for school ERPs and portals).
9:41▮▮ 85%☰Help & Tutorial⋮━━━━━━━━━━━━━━━━━━ loadingCodingEasilyAndroid Tutorial (Kotlin)WWhat is Android?IInstall Android StudioFFirst Android App
Student Diary Help screen = codingeasily.in in a WebView

Basic WebView

XML + Kotlin
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET" />

// Activity
binding.webView.settings.javaScriptEnabled = true
binding.webView.webViewClient = WebViewClient()          // keep links inside the app
binding.webView.loadUrl("https://codingeasily.in/")

// local HTML from assets/ folder
binding.webView.loadUrl("file:///android_asset/privacy.html")

// HTML string
binding.webView.loadDataWithBaseURL(null, "<h1>Hello</h1><p>From Kotlin</p>", "text/html", "UTF-8", null)

WebViewClient and progress

XML – res/layout/fragment_help.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.progressindicator.LinearProgressIndicator
        android:id="@+id/progress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:indeterminate="true" />
</FrameLayout>

Back button inside the WebView

Back pressedwebView.canGoBack()?yes → goBack()previous pageno → leave screennormal back
Users expect Back to go to the previous web page first

Real example: Help screen

Kotlin – ui/help/HelpFragment.kt (complete)
package com.codingeasily.studentdiary.ui.help

import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.OnBackPressedCallback
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import com.codingeasily.studentdiary.databinding.FragmentHelpBinding

/** Shows the online Android tutorial inside the app with a WebView. */
class HelpFragment : Fragment() {

    private var _binding: FragmentHelpBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        _binding = FragmentHelpBinding.inflate(inflater, container, false)
        return binding.root
    }

    @SuppressLint("SetJavaScriptEnabled")
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.webView.settings.javaScriptEnabled = true
        binding.webView.webViewClient = object : WebViewClient() {
            override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                _binding?.progress?.isVisible = true
            }
            override fun onPageFinished(view: WebView?, url: String?) {
                _binding?.progress?.isVisible = false
            }
        }
        // After rotation restore the page the user was reading, otherwise open the tutorial
        if (savedInstanceState == null || binding.webView.restoreState(savedInstanceState) == null) {
            binding.webView.loadUrl(HELP_URL)
        }

        // Back button goes back inside the WebView first
        requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (binding.webView.canGoBack()) binding.webView.goBack()
                else { isEnabled = false; requireActivity().onBackPressedDispatcher.onBackPressed() }
            }
        })
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        _binding?.webView?.saveState(outState)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    companion object {
        private const val HELP_URL = "https://codingeasily.in/tutorial/android/"
    }
}

Open other sites in the browser

Kotlin
binding.webView.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
        val url = request.url
        return if (url.host == "codingeasily.in") {
            false                                        // our site → load in the WebView
        } else {
            startActivity(Intent(Intent.ACTION_VIEW, url)) // others (YouTube, WhatsApp, tel:) → system
            true
        }
    }
}

JavaScript bridge

Kotlin + HTML
class AppBridge(private val context: Context) {
    @JavascriptInterface
    fun showToast(message: String) {
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
    }
}

binding.webView.addJavascriptInterface(AppBridge(this), "Android")

// in your web page (only on your own trusted site):
// <button onclick="Android.showToast('Saved from the web page!')">Save</button>

Turning a website into an app

  1. 1Make the website mobile-friendly first (responsive CSS)
  2. 2Native shell: toolbar, bottom navigation for the main sections
  3. 3WebView with WebViewClient, progress bar, back handling, pull-to-refresh
  4. 4Offline screen: show a native "No internet" view with Retry
  5. 5Native extras: push notifications, file upload/camera, share
A good hybrid app feels native

Common mistakes

  • No INTERNET permission → "net::ERR_CACHE_MISS".
  • Loading http:// pages → blocked by default; use HTTPS.
  • Rotation reloads the page → save and restore the WebView state (see HelpFragment).
  • File inputs (<input type="file">) do nothing → implement WebChromeClient.onShowFileChooser.

Summary

  • WebView + INTERNET + webViewClient + loadUrl.
  • Show progress in onPageStarted/onPageFinished; handle Back with canGoBack().
  • Send external links to the system; use a JS bridge only for trusted pages.
✅ Practice

Make a "Privacy Policy" screen that loads an HTML file from assets/, and a "Blog" screen that loads your website with a progress bar and SwipeRefreshLayout.

Frequently Asked Questions

Will Google Play accept an app that is only a WebView?
Apps that just wrap a website with no extra value can be rejected under the minimum functionality policy. Add native features: notifications, offline screens, native navigation, camera upload.
Why does my page open in Chrome instead of the WebView?
Without a WebViewClient, links open in the default browser. Set webView.webViewClient = WebViewClient().
Is enabling JavaScript unsafe?
It is fine for your own trusted pages. Never load untrusted URLs with a JavaScript interface attached, because that page could call your Kotlin code.
← Android Tutorial (Kotlin)
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

Next topicProject: Student Diary App (Plan & Setup) Your progress: 39 / 43 (91%) · Lesson 40 / 43 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free