当前位置: 首页 > article >正文

【Android】设计一个圆角矩形的WebView

设置一个圆角矩形的WebView

自定义RoundWebView

package com.example.webviewdialog;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.webkit.WebView;

import androidx.annotation.NonNull;

public class RoundWebView extends WebView {

    private Path mPath = new Path();
    private RectF mRectF = new RectF();

    private float[] mRadiusArray = {0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f};

    public RoundWebView(Context context) {
        this(context, null);
    }

    public RoundWebView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(@NonNull Context context, AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundWebView); // 读取xml styleable,attrs是xml属性的集合
        float defaultDp = context.getResources().getDimensionPixelSize(R.dimen.web_view_corner_radius);
        float radius = a.getDimension(R.styleable.RoundWebView_rwv_radius, defaultDp);
        float topLeftRadius = a.getDimension(R.styleable.RoundWebView_rwv_top_left_radius, 0);
        float topRightRadius = a.getDimension(R.styleable.RoundWebView_rwv_top_right_radius, 0);
        float bottomLeftRadius = a.getDimension(R.styleable.RoundWebView_rwv_bottom_left_radius, 0);
        float bottomRightRadius = a.getDimension(R.styleable.RoundWebView_rwv_bottom_right_radius, 0);
        a.recycle();

        if (radius > 0) {
            topLeftRadius = topRightRadius = bottomLeftRadius = bottomRightRadius = radius;
        }
        setRoundRadius(topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius);
    }

    /**
     * 设置四个角的圆角半径
     *
     * @param radius 所有圆角的半径
     */
    public void setRoundRadius(float radius) {
        float result = radius > 0 ? radius : 0;
        setRoundRadius(result, result, result, result);
    }

    /**
     * 设置四个角的圆角半径
     *
     * @param leftTopRadius     左上角半径
     * @param rightTopRadius    右上角半径
     * @param rightBottomRadius 右下角半径
     * @param leftBottomRadius  左下角半径
     */
    public void setRoundRadius(float leftTopRadius, float rightTopRadius,
                               float rightBottomRadius, float leftBottomRadius) {
        mRadiusArray[0] = leftTopRadius > 0 ? leftTopRadius : 0;
        mRadiusArray[1] = leftTopRadius > 0 ? leftTopRadius : 0;
        mRadiusArray[2] = rightTopRadius > 0 ? rightTopRadius : 0;
        mRadiusArray[3] = rightTopRadius > 0 ? rightTopRadius : 0;
        mRadiusArray[4] = rightBottomRadius > 0 ? rightBottomRadius : 0;
        mRadiusArray[5] = rightBottomRadius > 0 ? rightBottomRadius : 0;
        mRadiusArray[6] = leftBottomRadius > 0 ? leftBottomRadius : 0;
        mRadiusArray[7] = leftBottomRadius > 0 ? leftBottomRadius : 0;
        invalidate();
    }

    @Override
    public void onDraw(@NonNull Canvas canvas) {
        int scrollX = this.getScrollX();
        int scrollY = this.getScrollY();
        mPath.reset();
        mRectF.set(0, scrollY, scrollX + getWidth(), scrollY + getHeight());
        // 使用半角的方式,性能比较好
        mPath.addRoundRect(mRectF, mRadiusArray, Path.Direction.CW);
        canvas.clipPath(mPath);
        super.onDraw(canvas);
    }
}

activity_main.xml 布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ff0000"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="424dp"
        android:background="@drawable/web_view_bg"
        android:clipChildren="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <com.example.webviewdialog.RoundWebView
            android:id="@+id/web_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/transparent"
            android:visibility="visible"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity 

package com.example.webviewdialog

import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.net.http.SslError
import android.os.Bundle
import android.util.Log
import android.webkit.*
import android.view.View
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    companion object {
        const val TAG = "MainActivity"
    }

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val webView: RoundWebView = findViewById<RoundWebView>(R.id.web_view)
        val url = "https://www.baidu.com/"
        
        Log.d(TAG, "Starting to configure WebView")

        // 配置WebView设置
        webView.settings.apply {
            javaScriptEnabled = true
            domStorageEnabled = true
            cacheMode = WebSettings.LOAD_NO_CACHE
            
            // 支持自动适应屏幕
            useWideViewPort = true
            loadWithOverviewMode = true
            
            // 基本设置
            defaultTextEncodingName = "utf-8"
            loadsImagesAutomatically = true
            blockNetworkImage = false
            
            // 支持混合内容
            mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
            
            // 设置UA
            userAgentString = "Mozilla/5.0 (Linux; Android 11; Pixel) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36"
        }

        webView.webViewClient = object : WebViewClient() {
            override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                super.onPageStarted(view, url, favicon)
                Log.e(TAG, "onPageStarted: url = $url")
            }

            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                Log.e(TAG, "onPageFinished: url = $url")
            }

            override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
                view.loadUrl(request.url.toString())
                return true
            }

            override fun onReceivedError(
                view: WebView?,
                request: WebResourceRequest?,
                error: WebResourceError?
            ) {
                Log.e(TAG, "onReceivedError: error = ${error?.description}, code = ${error?.errorCode}")
                super.onReceivedError(view, request, error)
            }

            override fun onReceivedSslError(
                view: WebView?,
                handler: SslErrorHandler?,
                error: SslError?
            ) {
                handler?.proceed()
            }
        }

        webView.webChromeClient = WebChromeClient()
        try {
            Log.d(TAG, "Loading URL: $url")
            webView.loadUrl(url)
        } catch (e: Exception) {
            Log.e(TAG, "Error loading URL", e)
        }
    }

    override fun onDestroy() {
        val webView = findViewById<WebView>(R.id.web_view)
        webView.destroy()
        super.onDestroy()
    }
}

最后样式界面如下所示: 


http://www.kler.cn/a/545737.html

相关文章:

  • (2025)深度分析DeepSeek-R1开源的6种蒸馏模型之间的逻辑处理和编写代码能力区别以及配置要求,并与ChatGPT进行对比(附本地部署教程)
  • vue项目使用vite和vue-router实现history路由模式空白页以及404问题
  • 5、pod 详解 (kubernetes)
  • 【博客之星】GIS老矣尚能饭否?WebGIS项目实战经验与成果展示
  • 07-1.React学习笔记.React脚手架介绍
  • 如何获取,CPU,GPU,硬盘,网卡,内存等硬件性能监控与各项温度传感器
  • 动态规划——路径问题②
  • QML使用ChartView绘制折线图
  • Hybrid Automatic Repeat Request (HARQ)
  • 计算机网络知识速记:HTTP/2.0与HTTP/1.1
  • 业务干挂数据库,Oracle内存分配不足
  • 缓存机制与 Redis 在高性能系统中的应用
  • 亚冬会绽放“云端”,联通云如何点亮冰城“科技之光”?
  • AI前端开发的风险与规避:ScriptEcho赋能高效安全开发
  • AI赋能前端性能优化:效率与体验的完美平衡
  • Jenkins 新建配置 Freestyle project 任务 六
  • 深入解析 PCIe 的 iATU(Internal Address Translation Unit)及其工作原理
  • 数据结构(考研)
  • 无人机 ,遥控器与接收机之前的通信
  • ChartDB:一个基于Web的可视化数据库设计工具