【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()
}
}
最后样式界面如下所示: