m0_71234511 2024-11-19 09:10
浏览 12

Android WebView (kotlin) 在显示哔哩哔哩网站时候出现的问题

图一是浏览器打开哔哩哔哩的显示情况
图二是webview 显示的情况
这是为什么呢?
我的代码如下

// WebViewComposable程序,用来显示网页
@OptIn(ExperimentalMaterial3Api::class)
@SuppressLint("SetJavaScriptEnabled")
@Composable
fun WebViewComposable() {
    // 获取当前的上下文环境,用于后续创建WebView等相关操作
    val context = LocalContext.current as Activity
    // 创建一个可变状态变量来保存WebView实例,初始化为null,后续在创建WebView时赋值
    val webViewState = remember { mutableStateOf<WebView?>(null) }
    // 创建一个可变状态变量,用于表示网页是否正在加载,初始值为true,表示开始时处于加载状态
    var isLoading by remember { mutableStateOf(true) }
    // 创建一个AndroidView,用于在Compose UI中嵌入Android原生的View,这里用来嵌入WebView显示网页
    var isFullScreen by remember { mutableStateOf(false) } // 全屏状态
    AndroidView(
        // 设置创建WebView的工厂函数,在这里进行WebView的各种初始化设置
        factory = {
            WebView(context).apply {
                // 启用JavaScript,使网页可以执行JavaScript代码
                settings.javaScriptEnabled = true
                // 启用DOM存储,方便网页进行本地数据存储等操作
                settings.domStorageEnabled = true
                // 混合内容模式设置为宽松模式(MIXED_CONTENT_ALWAYS_ALLOW),谨慎使用,需确保网页资源安全性
                settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
                // 加入长按监听代码,先添加监听,后续再完善具体长按操作逻辑
                setOnLongClickListener {
                    // 获取长按的位置相关信息(例如坐标等),HitTestResult可用于后续判断长按的具体元素类型等
                    val hitTestResult = hitTestResult
                    // 获取触发长按操作的WebView实例,后续可基于此实例进行相关处理,比如判断元素类型后针对该WebView执行相应的文字复制、图片下载、视频下载等功能操作
                    val currentWebView = this
                    val elementType = hitTestResult.type
                    // 使用when语句判断元素类型,不同类型对应不同的处理逻辑,这里先只是简单打印日志示意,后续要替换为真正的功能实现代码
                    when (elementType) {
                        WebView.HitTestResult.IMAGE_TYPE -> {
                            // 获取图片的URL(这里假设图片是通过URL加载的,不同情况可能需要不同处理方式)
                            val imageUrl = hitTestResult.extra
                            if (imageUrl!= null) {
                                saveImageFromUrlToLocal(imageUrl, context)
                            }
                        }
                        WebView.HitTestResult.SRC_ANCHOR_TYPE -> {
                            Log.d("WebViewLongPress", "长按的元素是带有链接的文本等情况,按需添加对应处理")
                        }
                        WebView.HitTestResult.PHONE_TYPE -> {
                            Log.d("WebViewLongPress", "长按的元素是电话号码相关,按需添加对应处理")
                        }
                        WebView.HitTestResult.EDIT_TEXT_TYPE -> {
                            Log.d("WebViewLongPress", "长按的元素是普通文本,后续可添加文字复制逻辑")
                        }
                        else -> {
                            Log.d("WebViewLongPress", "长按的元素是其他类型,可进一步分析处理")
                        }
                    }
                    true
                }
                // 加载指定的网页URL
                loadUrl("https://www.bilibili.com/")
                // 设置WebView的客户端,用于监听网页加载的相关事件
                webViewClient = object : WebViewClient() {
                    override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                        if (!isFullScreen) {
                            isLoading = true
                        }
                    }

                    override fun onPageFinished(view: WebView?, url: String?) {
                        if (!isFullScreen) {
                            isLoading = false
                        }
                    }
                }
                 // 设置WebView的按键监听,用于处理返回键按下的操作
                setOnKeyListener { _, keyCode, event ->
                    if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP && canGoBack()) {
                        // 如果按下的是返回键,并且WebView可以返回上一页,则执行返回操作
                        goBack()
                        true
                    } else {
                        false
                    }
                }
                // 设置WebView使用宽屏视口,使网页能依据屏幕宽度自适应布局,有助于避免出现横向滚动条等布局问题
                settings.useWideViewPort = true
                // 让网页按概览模式加载,使网页初始显示时整体布局更合理,优化页面初次展示效果
                settings.loadWithOverviewMode = true
                //支持插件
                settings.textZoom = 100
                // 获取系统默认的User-Agent字符串,一般它能表明是Android系统下的请求,但可能需要进行修改使其更接近常见浏览器的User-Agent
                val defaultUserAgent = WebSettings.getDefaultUserAgent(context)
                // 自定义的User-Agent字符串,这里模拟Chrome浏览器的部分关键特征(可根据实际测试情况进一步优化调整)
                val customUserAgent = "$defaultUserAgent Chrome/118.0.0.0 Mobile Safari/537.36"
                // 设置WebView使用自定义的User-Agent,这样向服务器请求网页时,服务器可能会返回更适配常规浏览器显示效果的内容
                settings.userAgentString = customUserAgent
                // 设置WebView的页面布局算法为单栏模式,有助于在不同屏幕尺寸下让网页元素更好地自适应排列,避免出现布局错乱的情况
                // 尤其对于一些采用流式布局等的网页,能让其更合理地展示内容,类似浏览器中常见的页面布局自适应效果
                settings.layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN
                // 开启对 HTML5 的本地存储功能支持,方便网页使用HTML5的相关API进行本地数据存储等操作,很多网页利用此功能来提升用户体验,比如记住用户设置等
                settings.domStorageEnabled = true
                // 设置WebView的缓存模式为LOAD_DEFAULT,它会根据网络情况等自动选择合适的缓存策略,
                // 例如在有网络时会合理利用已有缓存并更新部分资源,离线时尝试使用缓存内容展示网页,以此来优化网页加载及离线使用等情况
                settings.cacheMode = WebSettings.LOAD_DEFAULT
                settings.javaScriptCanOpenWindowsAutomatically = true
                settings.allowFileAccess = true
                settings.allowContentAccess = true
                settings.loadsImagesAutomatically = true
                settings.mediaPlaybackRequiresUserGesture = false
                webViewState.value = this

            }
        },
        // 设置AndroidView的大小充满整个屏幕
        modifier = Modifier.fillMaxSize()
    )
    // 根据isLoading的值来决定是否显示加载中的提示,例如圆形进度条
    if (isLoading) {
        Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
            CircularProgressIndicator(modifier = Modifier.size(80.dp))
        }
    }
}

图一

img


图二

img

展开全部

  • 写回答

0条回答 默认 最新

      编辑
      预览

      报告相同问题?

      问题事件

      • 修改了问题 11月19日
      • 创建了问题 11月19日

      悬赏问题

      • ¥15 宝塔面板一键迁移使用不了
      • ¥15 求一个按键录像存储到内存卡的ESP32CAM代码
      • ¥15 如何单独修改下列canvas推箱子代码target参数?,插入图片代替其形状,就是哪个绿色的圆圈每关用插入的图片替代
      • ¥20 四叉树的创建和输出问题
      • ¥15 javaweb连接数据库,jsp文件加载不出来
      • ¥15 matlab关于高斯赛德尔迭代的应用编撰。(相关搜索:matlab代码|迭代法)
      • ¥15 损失匹配问题,求解答
      • ¥15 3500常用汉字书法体检测数据集下载
      • ¥15 odoo17在制造模块或采购模块良品与次品如何分流和在质检模块下如何开发
      • ¥15 Qt音乐播放器的音乐文件相对路径怎么写
      手机看
      程序员都在用的中文IT技术交流社区

      程序员都在用的中文IT技术交流社区

      专业的中文 IT 技术社区,与千万技术人共成长

      专业的中文 IT 技术社区,与千万技术人共成长

      关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

      关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

      客服 返回
      顶部