LoginSignup
1
0

【Android】ネイティブからWebView内の要素を非表示にする/特定の位置までスクロールする

Last updated at Posted at 2024-03-29

はじめに

AndroidのWebViewはただページを表示して終わりではありません。
JavaScriptのコードをネイティブ側で書くことで、WebView内の部品をあれこれいじるすることができます!
今回は下記の2つのサンプルコードをご用意しました。

  • WebView内の部品を非表示にする
  • ネイティブ側で設置したボタンからWebViewの特定の位置にニュルっとスクロールする

なお、筆者はJavaScript一切経験していない人間なので書き方などお見苦しい点があるかと思いますがご容赦ください。

WebView内の部品を非表示にする

Android Developersのヘッダー部分を非表示にする形で試してみようと思います。
修正前はこのような形で、上部にハンバーガーメニューやログインボタンが配置されているヘッダーが存在しています。

Screenshot_20240330_034944.png

まずは該当のWebサイトをChromeの検証ツールなどを用いて開き、非表示にしたい要素を見つけます。
どうやらこのdevsite-top-logo-row-wrapper-wrapperというのがヘッダー部分の要素のようですね。

スクリーンショット 2024-03-30 3.13.26.png

次に、ネイティブのコード内で下記のようにjsのコードを書き、これをonPageFinished()など任意の場所で呼びます。

MainActivity.kt

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding?.root)

        val webView = binding?.webview
        webView?.settings?.javaScriptEnabled = true
        webView?.webViewClient = object: WebViewClient() {
            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                view?.loadUrl(
                    "javascript:(function() { " +
                            "document.getElementsByClassName('devsite-top-logo-row-wrapper-wrapper')[0].style.display = 'none';" +
                            "})()"
                )
            }
        }

        webView?.loadUrl("https://developer.android.com/?hl=ja")
    }

通常のJavaScriptの関数だとKotlinのようにfun test(){...}のように書くのですが、loadUrl内で関数を実行する場合は記法が若干異なるので注意が必要です。
(JavaScriptと同じような関数の記法で試したところ正常に動きませんでした)

これを実行すると下記のような形でヘッダー部分が非表示になっています!

none.png

ちなみに上記ではstyle.display = 'none'を使用していますが、style.visibility = 'hidden'を使用すると下記のような形でスペースは確保されたまま要素が非表示になります。

hidden.png

ネイティブ側で設置したボタンからWebViewの特定の位置にニュルっとスクロールする

次はサイト下部にあるYouTubeのボタンまでニュルっとスクロールさせてみましょう。

これまでと同じように検証ツールで該当の要素を確認します。

スクリーンショット 2024-03-30 3.51.40.png

要素名は「devsite-footer-promo」だとわかりましたが、XやLinkedInも同じ要素名になっていますね。
このような場合は、index指定することによって該当の要素を抜き出せます。
今回はX→[0], YouTube→[1], LinkedIn→[2]という形で並んでいるため、[1]を指定します。

肝心のスクロール処理に関してはJavaScriptのelement.scrollIntoViewメソッドを使用します。

MainActivity.kt

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding?.root)

        val webView = binding?.webview
        webView?.settings?.javaScriptEnabled = true
        webView?.webViewClient = object : WebViewClient() {
            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                view?.loadUrl(
                    "javascript:document.getElementsByClassName('devsite-footer-promo')[1].scrollIntoView({behavior: 'smooth'});"
                )
            }
        }

        webView?.loadUrl("https://developer.android.com/?hl=ja")
    }

こうすることで指定の位置までニュルッとスクロールするようになります!

scrollToYouTube.gif

ちなみにニュルッとスクロールさせたくない場合はscrollIntoView()とすればOKです。

所感

フロントエンドのエンジニアの方に依頼しなくてもこのようにネイティブからある程度サイト内を編集することができるのはとても助かるなと思いました。
今回ご紹介したのはほんの一部ですが、JavaScriptのメソッドをそのまま書いているだけなのでやりようによってはかなり色んなことができるのではないかと思います。
一方で、コード内のJavaScript構文は全てダブルクオーテーションで囲まなければならず、補完やコンパイルエラーを検知できないのはなかなか辛いなといった印象です。
この辺りうまいやり方があったら知りたいですね!

ソースコード

こちらに格納しております。
https://github.com/bayastea/EditWebView

参考サイト

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0