Open In App

Android – Search a Text in WebView

Improve
Improve
Like Article
Like
Save
Share
Report

WebView allows you to display web content in your activity layout or Fragment but lacks some of the features of fully-developed browsers. A WebView is useful when you need to increase control over the UI and advanced configuration options that will allow you to embed web pages in a specially-designed environment for your app.

Note: To know more about WebView please refer to Android WebView in Kotlin or How to Use WebView in Android. In this article, we will see how we can search keywords(texts) inside a WebView using both Java and Kotlin.

A sample video is given below to get an idea about what we are going to do in this article.

Class Hierarchy

Java:

java.lang.Object
  ↳ android.view.View
    ↳ android.view.ViewGroup
      ↳ android.widget.AbsoluteLayout
        ↳ android.webkit.WebView

Kotlin:

kotlin.Any
  ↳ android.view.View
  ↳ android.view.ViewGroup
  ↳ android.widget.AbsoluteLayout
  ↳ android.webkit.WebView

Step by Step Implementation

Step 1: Create a new project in Android Studio

To create a new project in Android Studio please refer to  How to Create/Start a New Project in Android Studio.

Step 2: Add Permissions in the AndroidManifest.xml File

In order to access the internet we have to add Internet permission in the AndroidManifest.xml file.

<uses-permission android:name=”android.permission.INTERNET” />

Step 3: Working with the activity_main.xml file

Navigate to app > res > layout > activity_main.xml and add the below code to it. Comments are added in the code to get to know in detail. 

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
  
    <!-- Web-view on the Screen -->
    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    
    <!--ProgressBar for loading indicator-->
    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/webView" />
  
</androidx.constraintlayout.widget.ConstraintLayout>


Step 4: Adding menu items in the Menu Resource file

In order to know what is menu items or how to add menu items please refer to Android Menus and How to Create Menu Folder & Menu File in Android Studio?

XML




<?xml version="1.0" encoding="utf-8"?>
  
    <!--Search menu item-->
    <item
        android:id="@+id/itemSearch"
        android:icon="@drawable/ic_search_24"
        android:title="Search"
        app:actionViewClass="androidx.appcompat.widget.SearchView"
        app:showAsAction="always|collapseActionView" />
    
      <!--make sure you add the collapseActionView in showsAsAction-->
    
    <!--menu item to jump to next keyword-->
    <item
        android:id="@+id/itemNext"
        android:icon="@drawable/ic_arrow_down_24"
        android:title="Next Item"
        android:visible="false"
        app:showAsAction="always"/>
  
    <!--menu item to jump to previous keyword-->
    <item
        android:id="@+id/itemPrevious"
        android:icon="@drawable/ic_arrow_up_24"
        android:title="Previous Item"
        android:visible="false"
        app:showAsAction="always"/>
  
</menu>


Step 5: Working with the MainActivity file 

Navigate to app > java > your app’s package name > MainActivity file and add the below code to it. Comments are added in the code to get to know in detail.

Note: In the below code ViewBinding is used in order to reduce the boilerplate code and generated instances of the views of the current layout. This replaces the use of findViewById(). To know more about ViewBinding and how to enable ViewBinding please refer to View Binding in Android Jetpack.

Kotlin




import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView
import com.example.geeksforgeeks.databinding.ActivityMainBinding
  
class MainActivity : AppCompatActivity() {
    
    private var binding: ActivityMainBinding? = null
    private var createMenu: Menu? = null
  
    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding!!.getRoot())
  
        // this will enable the javascript in the WebView
        binding!!.webView.getSettings().setJavaScriptEnabled(true)
  
        // load https://www.geeksforgeeks.org url in the WebView.
        binding!!.webView.loadUrl("https://www.geeksforgeeks.org")
  
        // WebViewClient allows you to handle
        // onPageFinished and override Url loading.
        binding!!.webView.setWebViewClient(object : WebViewClient() {
            override fun onPageStarted(view: WebView, url: String, favicon: Bitmap) {
                super.onPageStarted(view, url, favicon)
                // set the visibility to visible when
                // the page starts loading
                binding!!.progressBar.setVisibility(View.VISIBLE)
            }
  
            override fun onPageFinished(view: WebView, url: String) {
                super.onPageFinished(view, url)
                // set the visibility to gone when 
                // the page gets loaded completely
                binding!!.progressBar.setVisibility(View.GONE)
            }
        })
    }
  
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        super.onCreateOptionsMenu(menu)
        // create an reference of menu
        createMenu = menu
        val inflater = menuInflater
        inflater.inflate(R.menu.menu, menu)
        return true
    }
  
    @SuppressLint("NonConstantResourceId")
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.itemSearch -> {
                // create a searchView inside the actionbar 
                // when search menu item is clicked
                val searchView = item.actionView as SearchView
                  
                // set the width to maximum
                searchView.maxWidth = Int.MAX_VALUE
                searchView.queryHint = "Search any keyword.."
                  
                // set a listener when the start typing in the SearchView
                searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
                    override fun onQueryTextSubmit(query: String): Boolean {
                        // clear the focus when
                        // the text is submitted
                        searchView.clearFocus()
                        return false
                    }
  
                    override fun onQueryTextChange(query: String): Boolean {
                        // When the query length is greater
                        // than 0 we will perform the search
                        if (query.length > 0) {
                              
                            // findAllAsync finds all instances
                            // on the page and 
                            // highlights them,asynchronously.
                            binding!!.webView.findAllAsync(query)
                              
                            // set the visibility of nextItem 
                            // and previous item to true
                            createMenu!!.getItem(1).isVisible = true
                            createMenu!!.getItem(2).isVisible = true
                        } else {
                            binding!!.webView.clearMatches()
                              
                            // set the visibility of nextItem 
                            // and previous item to false 
                            // when query length is 0
                            createMenu!!.getItem(1).isVisible = false
                            createMenu!!.getItem(2).isVisible = false
                        }
                        return true
                    }
                })
            }
            R.id.itemNext ->
                // findNext highlights and scrolls to the next match
                // found by findAllAsync(String),
                // wrapping around page boundaries as necessary.
                // true scrolls to the next match
                binding!!.webView.findNext(true)
            R.id.itemPrevious ->
                // findNext highlights and scrolls to the next match found 
                // by findAllAsync(String),
                // wrapping around page boundaries as necessary.
                // false scrolls to the previous match
                binding!!.webView.findNext(false)
        }
        return super.onOptionsItemSelected(item)
    }
}


Java




import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.example.geeksforgeeks.databinding.ActivityMainBinding;
  
public class MainActivity extends AppCompatActivity {
  
    private ActivityMainBinding binding;
    private Menu createMenu;
  
    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
  
        // this will enable the javascript in the WebView
        binding.webView.getSettings().setJavaScriptEnabled(true);
  
        // load https://www.geeksforgeeks.org url in the WebView.
        binding.webView.loadUrl("https://www.geeksforgeeks.org");
  
        // WebViewClient allows you to handle
        // onPageFinished and override Url loading.
        binding.webView.setWebViewClient(new WebViewClient(){
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                // set the visibility to visible when 
                  // the page starts loading
                binding.progressBar.setVisibility(View.VISIBLE);
            }
  
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                // set the visibility to gone when the page 
                // gets loaded completely
                binding.progressBar.setVisibility(View.GONE);
            }
        });
    }
  
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        // create an reference of menu
        createMenu = menu;
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }
  
    @SuppressLint("NonConstantResourceId")
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case R.id.itemSearch:
                // create a searchView inside the actionbar
                // when search menu item is clicked
                SearchView searchView = (SearchView) item.getActionView();
                  
                // set the width to maximum
                searchView.setMaxWidth(Integer.MAX_VALUE);
                searchView.setQueryHint("Search any keyword..");
                  
                // set a listener when the start typing in the SearchView
                searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                    @Override
                    public boolean onQueryTextSubmit(String query) {
                        // clear the focus when 
                        // the text is submitted
                        searchView.clearFocus();
                        return false;
                    }
  
                    @Override
                    public boolean onQueryTextChange(String query) {
                        // When the query length is greater 
                        // than 0 we will perform the search
                        if(query.length()>0){
                             
                            // findAllAsync finds all instances
                            // on the page and 
                            // highlights them,asynchronously.
                            binding.webView.findAllAsync(query);
                              
                            // set the visibility of nextItem 
                            // and previous item to true
                            createMenu.getItem(1).setVisible(true);
                            createMenu.getItem(2).setVisible(true);
  
                        }else{
                            binding.webView.clearMatches();
                              
                            // set the visibility of nextItem 
                            // and previous item to false 
                            // when query length is 0
                            createMenu.getItem(1).setVisible(false);
                            createMenu.getItem(2).setVisible(false);
                        }
                        return true;
                    }
                });
                break;
            case R.id.itemNext:
                // findNext highlights and scrolls to the next match
                // found by findAllAsync(String),
                // wrapping around page boundaries as necessary.
                // true scrolls to the next match
                binding.webView.findNext(true);
                break;
            case R.id.itemPrevious:
                // findNext highlights and scrolls to the next match 
                // found by findAllAsync(String),
                // wrapping around page boundaries as necessary.
                // false scrolls to the previous match
                binding.webView.findNext(false);
        }
        return super.onOptionsItemSelected(item);
  
    }
}


Output:



Last Updated : 01 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads