簡體   English   中英

如何在 android webview ( kotlin ) 中添加帶有確認消息的返回按鈕

[英]How to add back button with confirmation message in android webview ( kotlin )

我在 kotlin 中創建了一個 android webview。 我想添加帶有上一頁 web 視圖檢查和沒有 web 視圖最終確認的返回按鈕,帶有是沒有退出選項。 現在 webview window 在第一次后壓中直接關閉。 請建議我怎樣才能做到這一點?

這是我的 homeactivity.kt

package murait.the.android.mania

import android.annotation.SuppressLint
import android.app.ProgressDialog
import android.content.Intent
import android.net.ConnectivityManager
import android.net.Uri
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.webkit.*
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat
import androidx.navigation.ui.AppBarConfiguration
import com.google.android.gms.ads.*
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
import com.google.android.material.navigation.NavigationView
import murait.the.android.mania.databinding.ActivityHomeBinding
import android.webkit.WebSettings





class HomeActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    private lateinit var appBarConfiguration: AppBarConfiguration
    private lateinit var binding: ActivityHomeBinding
    private val url = "https://www.demopage.com/"
    private var currentUrl = ""
    private val FILECHOOSER_RESULTCODE = 190
    private var mInterstitialAd: InterstitialAd? = null
    private var interAdRequest: AdRequest? = null
    private var progressDialog: ProgressDialog? = null
    private var mUploadMessage: ValueCallback<Array<Uri>>? = null
    private var prefManager: PrefManager? = null
    private var mAdIsLoading: Boolean = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityHomeBinding.inflate(layoutInflater)
        setContentView(binding.root)

        setSupportActionBar(binding.appBarHome.toolbar)

        MobileAds.initialize(this) {}

        prefManager = PrefManager(baseContext)
        progressDialog = ProgressDialog(this)
        progressDialog?.setMessage("Loading...")
        

        val actionBarDrawerToggle = ActionBarDrawerToggle(
            this,
            binding.drawerLayout,
            binding.appBarHome.toolbar,
            R.string.app_name,
            R.string.app_name
        );

        loadBannerAds()
        loadInterAds()

        if (isOnline()) {
            binding.appBarHome.contentMain.llError.rlContent.visibility = View.GONE
            binding.appBarHome.contentMain.webView.visibility = View.VISIBLE
            startWebView(url)
        } else {
            binding.appBarHome.contentMain.llError.rlContent.visibility = View.VISIBLE
            binding.appBarHome.contentMain.webView.visibility = View.GONE
            if (progressDialog != null && progressDialog?.isShowing == true)
                progressDialog?.dismiss()
        }
    }

    private fun loadInterAds() {
        var interAdRequest = AdRequest.Builder().build()

        InterstitialAd.load(
            this, getString(R.string.interstitial_full_screen), interAdRequest,
            object : InterstitialAdLoadCallback() {
                override fun onAdFailedToLoad(adError: LoadAdError) {
                    mInterstitialAd = null
                    mAdIsLoading = false
                }

                override fun onAdLoaded(interstitialAd: InterstitialAd) {
                    mInterstitialAd = interstitialAd
                    mAdIsLoading = false
                }
            }
        )
    }

    private fun showInterAds(url: String) {
        if (mInterstitialAd != null) {
            mInterstitialAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
                override fun onAdDismissedFullScreenContent() {
                    binding.appBarHome.contentMain.webView.loadUrl(url)
                    loadInterAds()
                }

                override fun onAdFailedToShowFullScreenContent(adError: AdError?) {

                }

                override fun onAdShowedFullScreenContent() {
                    mInterstitialAd = null;
                }
            }
            mInterstitialAd?.show(this)
        } else {
            binding.appBarHome.contentMain.webView.loadUrl(url)
        }
    }

    @SuppressLint("SetJavaScriptEnabled")
    private fun startWebView(url: String) {

        binding.appBarHome.contentMain.webView.webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
                prefManager?.addVar()
                if (mInterstitialAd != null && prefManager?.tVar?.rem(PrefManager.ADS_SHOW_TIME) == 0) {
                    showInterAds(url.toString())
                } else {
                    view?.loadUrl(url.toString())
                }
                return true
            }

            //Show loader on url load
            /*override fun onLoadResource(view: WebView?, url: String?) {
                if (progressDialog == null) {
                    progressDialog = ProgressDialog(this@HomeActivity)
                    progressDialog?.setMessage("Loading...")
                }
                if (progressDialog != null && progressDialog?.isShowing == false)
                    progressDialog?.show()
                prefManager!!.addVar()
            }*/


            override fun onPageFinished(view: WebView?, url: String?) {
                try {
                    if (progressDialog!!.isShowing) {
                        progressDialog!!.dismiss()
                        prefManager!!.addVar()
                        progressDialog = null
                    }
                } catch (exception: Exception) {
                    exception.printStackTrace()
                }
            }

            override fun onReceivedHttpError(
                view: WebView?,
                request: WebResourceRequest?,
                errorResponse: WebResourceResponse?
            ) {
                //super.onReceivedHttpError(view, request, errorResponse);
                if (progressDialog != null && progressDialog?.isShowing == false) progressDialog?.dismiss()
            }
        }
        binding.appBarHome.contentMain.webView.webChromeClient = object : WebChromeClient() {
            override fun onShowFileChooser(
                webView: WebView,
                filePathCallback: ValueCallback<Array<Uri>>,
                fileChooserParams: FileChooserParams
            ): Boolean {
                mUploadMessage?.onReceiveValue(null)
                mUploadMessage = filePathCallback
                val i = Intent(Intent.ACTION_GET_CONTENT)
                i.addCategory(Intent.CATEGORY_OPENABLE)
                i.type = "*/*"
                startActivityForResult(
                    Intent.createChooser(i, "File Chooser"),
                    FILECHOOSER_RESULTCODE
                )
                return true
            }


        }


        // Other webview options
        binding.appBarHome.contentMain.webView.settings.javaScriptEnabled = true
        binding.appBarHome.contentMain.webView.settings.domStorageEnabled = true
        // Other webview options
        binding.appBarHome.contentMain.webView.settings.loadWithOverviewMode = true
        binding.appBarHome.contentMain.webView.settings.useWideViewPort = true
        binding.appBarHome.contentMain.webView.scrollBarStyle = WebView.SCROLLBARS_OUTSIDE_OVERLAY
        binding.appBarHome.contentMain.webView.isScrollbarFadingEnabled = false
        binding.appBarHome.contentMain.webView.settings.builtInZoomControls = false
        binding.appBarHome.contentMain.webView.settings.allowContentAccess = true

        binding.appBarHome.contentMain.webView.setDownloadListener(DownloadListener { url, userAgent, contentDisposition, mimetype, contentLength ->
            val i = Intent(Intent.ACTION_VIEW)
            i.data = Uri.parse(url)
            startActivity(i)
        })

        currentUrl = url
        //Load url in webview
        //Load url in webview
        binding.appBarHome.contentMain.webView.loadUrl(url)
    }

    private fun loadBannerAds() {
        val adRequest = AdRequest.Builder().build()
        binding.appBarHome.contentMain.adView.loadAd(adRequest)

        binding.appBarHome.contentMain.adView.adListener = object : AdListener() {
            override fun onAdLoaded() {
                binding.appBarHome.contentMain.adView.visibility = View.VISIBLE
            }

            override fun onAdFailedToLoad(adError: LoadAdError) {
                binding.appBarHome.contentMain.adView.visibility = View.GONE
            }

            override fun onAdOpened() {
                // Code to be executed when an ad opens an overlay that
                // covers the screen.
            }

            override fun onAdClicked() {
                // Code to be executed when the user clicks on an ad.
            }

            override fun onAdClosed() {
                // Code to be executed when the user is about to return
                // to the app after tapping on an ad.
            }
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        //menuInflater.inflate(R.menu.home, menu)
        return true
    }

    override fun onBackPressed() {
        if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
            binding.drawerLayout.closeDrawer(GravityCompat.START)
        } else {
            super.onBackPressed()
        }
    }


    private fun closeDrawer() {
        binding.drawerLayout.closeDrawer(GravityCompat.START)
    }

    override fun onNavigationItemSelected(menuItem: MenuItem): Boolean {
        closeDrawer()
        when (menuItem.getItemId()) {

        }
        return false
    }

    private fun isOnline(): Boolean {
        val cm = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
        val netInfo = cm.activeNetworkInfo
        return netInfo != null && netInfo.isConnectedOrConnecting
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        super.onActivityResult(requestCode, resultCode, intent)
        if (requestCode == FILECHOOSER_RESULTCODE) {
            if (null == mUploadMessage || intent == null || resultCode != RESULT_OK) {
                return
            }
            val dataString = intent.dataString
            mUploadMessage!!.onReceiveValue(arrayOf(Uri.parse(dataString)))
            mUploadMessage = null
        }
    }
}

這是我的activity_home.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        android:id="@+id/app_bar_home"
        layout="@layout/app_bar_home"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</androidx.drawerlayout.widget.DrawerLayout>

我認為 onBackPressed 中的onBackPressed super.onBackPressed()會導致立即退出:

override fun onBackPressed() {
    if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
        binding.drawerLayout.closeDrawer(GravityCompat.START)
    } else {
        super.onBackPressed()
    }
}

與其只是一個裸露的super.onBackPressed() ,不如用一個Snackbar包裝它,例如:

    } else {
        Snackbar.make(
            findViewById(android.R.id.content),
            "Are you sure to close?",
            Snackbar.LENGTH_LONG
        ).setAction("close") { super.onBackPressed() }.show()
    }

這些天推薦的方法是向OnBackPressedDispatcher添加回調 你可以添加一堆來創建處理程序的層次結構,這樣你就可以有一個來檢查你是否會丟失未保存的數據,一個來檢查你是否要退出應用程序,等等。(其中一個他們給出的示例是用於處理WebView后退導航)

回調按添加順序排列優先級,最近的在前,您可以啟用和禁用它們以“打開和關閉”並允許較低優先級的回調處理后按。 如果沒有添加/啟用,它只會執行通常的onBackPressed處理。

你必須與你的 WebView 交互並協調告訴它 go 回溯歷史,並讓它告訴你的片段/活動它沒有更多的頁面可以返回(所以你可以顯示一個警告對話框),但我猜你想要這樣的東西:

class HomeActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    lateinit var backPressedCallback: OnBackPressedCallback

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        backPressedCallback = onBackPressedDispatcher.addCallback(this) {
            callWebViewBack()
        }
    }
    ...

    fun callWebViewBack() {
        // send a "Back" message to your webview
    }

    fun onWebViewBackedOut() {
        // this is a terrible name, but when your webview gets the "Back" message
        // but it has no more history to back through, it needs to call this function
        // so the Activity can display the confirmation dialog here
        showExitConfirmationDialog()
    }

    // when you handle the result from your dialog, you can call this to disable
    // the handler that tells the webview to go back, then send the back button event
    // (which will invoke the next callback in the chain, handling something else,
    // if you've added one, otherwise it'll do the usual back button behaviour)
    fun exitWebView() {
        backPressedCallback.disable()
        onBackPressed()
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM