简体   繁体   English

如何在 android webview ( kotlin ) 中添加带有确认消息的返回按钮

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

I created a android webview in kotlin.我在 kotlin 中创建了一个 android webview。 I want to add back button with previous page web view check and and no web view final confirmation with yes no exit option.我想添加带有上一页 web 视图检查和没有 web 视图最终确认的返回按钮,带有是没有退出选项。 Right now webview window directly closed in first back press.现在 webview window 在第一次后压中直接关闭。 Kindly suggest how can I achieve this?请建议我怎样才能做到这一点?

This my homeactivity.kt这是我的 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
        }
    }
}

This my activity_home.xml这是我的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>

I think this super.onBackPressed() in onBackPressed causes immediate exit:我认为 onBackPressed 中的onBackPressed super.onBackPressed()会导致立即退出:

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

In stead of just a bare super.onBackPressed() , wrap it with a Snackbar for example:与其只是一个裸露的super.onBackPressed() ,不如用一个Snackbar包装它,例如:

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

The recommended way these days is to add a callback to the OnBackPressedDispatcher .这些天推荐的方法是向OnBackPressedDispatcher添加回调 You can add a bunch of these to create a hierarchy of handlers, so you can have one that checks if you'll lose unsaved data, one that checks if you're about to back out of the app, etc. (One of the examples they give is for handling WebView back navigation)你可以添加一堆来创建处理程序的层次结构,这样你就可以有一个来检查你是否会丢失未保存的数据,一个来检查你是否要退出应用程序,等等。(其中一个他们给出的示例是用于处理WebView后退导航)

The callbacks are prioritised by the order they were added, most-recent first, and you can enable and disable them to "turn them on and off" and allow a lower-priority callback to handle the back press.回调按添加顺序排列优先级,最近的在前,您可以启用和禁用它们以“打开和关闭”并允许较低优先级的回调处理后按。 If none are added/enabled, it just does the usual onBackPressed handling.如果没有添加/启用,它只会执行通常的onBackPressed处理。

You'd have to interface with your WebView and coordinate telling it to go back through the history, and having it tell your Fragment/Activity that it has no more pages to back through (so you can show a warning dialog), but I guess you want something like this:你必须与你的 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