Android 怎么给 weview 设置圆角

这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

前言

项目中遇到一个跟H5交互的问题,需要我们做一个弹框来显示一个H5的编辑页面,本来很简单的东西,就是写一个自定义Dialog,添加一个webview,设置好webview的属性,然后直接加载就好了,需求很简单,只是UI设计上,需要给弹框设置圆角,其实也没问题,那就设置呗,但是却遇到了问题。。。

UI添加圆角的方法

1.通过shape文件,设置圆角:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="rectangle">

   <solid android:color="@color/white" />
   <corners
      android:bottomLeftRadius="0px"
      android:bottomRightRadius="0px"
      android:topLeftRadius="12px"
      android:topRightRadius="12px" />

</shape>

复制代码

2.通过代码手动设置圆角:

public static StateListDrawable getBackGroundDrawable(int strokeRoundWidth, float roundRadius, int strokeColor, int fillColor) {
    float[] radii = new float[]{roundRadius, roundRadius, roundRadius, roundRadius, roundRadius, roundRadius, roundRadius, roundRadius};
    StateListDrawable drawable = new StateListDrawable();

    GradientDrawable pressState = new GradientDrawable();//创建drawable
    pressState.setColor(caculateColor(fillColor, Color.BLACK, 0.1f));
    pressState.setCornerRadii(radii);
    pressState.setStroke(strokeRoundWidth, strokeColor);

    GradientDrawable eableState = new GradientDrawable();//创建drawable
    eableState.setColor(caculateColor(fillColor, Color.WHITE, 0.5f));
    eableState.setCornerRadii(radii);
    eableState.setStroke(0, strokeColor);

    GradientDrawable commonState = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, new int[]{Color.BLACK, fillColor});
    commonState.setColor(fillColor);
    commonState.setCornerRadii(radii);
    commonState.setStroke(strokeRoundWidth, strokeColor);

    drawable.addState(new int[]{-android.R.attr.state_enabled}, eableState);
    drawable.addState(new int[]{android.R.attr.state_pressed}, pressState);
    drawable.addState(new int[]{}, commonState);

    return drawable;
}
复制代码

通过setBackGround(Drawable drawable) 方法设置背景

给webview 设置圆角

1.通过给webview 添加外层布局,给布局设置圆角,设置内边距,实现加载页面有圆角


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   >
   <RelativeLayout
      android:id="@+id/rel_webview"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:padding="2dp"
      android:background="@drawable/drawable_webview_bg"
      >

      <com.tencent.smtt.sdk.WebView
         android:id="@+id/wv_course_detail_summary"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         >
      </com.tencent.smtt.sdk.WebView>
   </RelativeLayout>

</RelativeLayout>
复制代码

2.通过设置webview的Background

1、先将layout文件中的 WebView控件取消硬件加速 android:layerType="software",(以确保第2步有效) 2、在Java代码中,将WebView控件背景色设为透明 web.setBackgroundColor(0);
3、获取一个圆角的Bitmap实例(网上有大把的实现方法);
4、通过 Bitmap实例获取一个 BitmapDrawable实例 BitmapDrawable bitmapDrawable = new BitmapDrawable(bitmap); 5、将 BitmapDrawable实例 BitmapDrawable 设置成WebView控件的背景 web.setBackground(bitmapDrawable);

不过,由于 web.setBackground 是 Android v4.1.2 (API Level 16)才开始支持,因此,这个功能也只能在 API Level 16及其以上实现。

以上方法,方法一肯定可以,但是对我项目中的需求,满足不了,因为webview的显示内容会被padding缩小,导致如果webview有加载的内容,有其他弹框弹出,覆盖区域只有webview加载的内容,会有2dp的白色边框;方法二,没有实际测试,但是目测不太靠谱,大家可以试试

我使用了第三种方法 3.自定义webview,通过draw方法绘制圆角,进行裁剪边缘

public class MyRoundedWebView extends CoreWebView {
    private Context context;

    private int width;

    private int height;

    private int radius;

    public MyRoundedWebView(Context context) {
        super(context);
        initialize(context);
    }

    public MyRoundedWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize(context);
    }

    private void initialize(Context context) {
        this.context = context;
    }

   
    @Override
    protected void onSizeChanged(int newWidth, int newHeight, int oldWidth, int oldHeight) {
        super.onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);

        width = newWidth;

        height = newHeight;
        
        //设置圆角
        radius = PHSizeUtils.mm2px(context, 46f);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Path path = new Path();

        path.setFillType(Path.FillType.INVERSE_WINDING);

        path.addRoundRect(new RectF(0, getScrollY(), width, getScrollY() + height), radius, radius, Path.Direction.CW);

        canvas.drawPath(path, createPorterDuffClearPaint());
    }
    //使用Porter Duff Xfer模式从屏幕"清除"该区域
    private Paint createPorterDuffClearPaint() {
        Paint paint = new Paint();

        paint.setColor(Color.TRANSPARENT);

        paint.setStyle(Paint.Style.FILL);

        paint.setAntiAlias(true);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

        return paint;
    }
}
复制代码

这样实现后,webview 加载完后,显示的是完整的控件,不管加载的url里面有什么弹框,都是按照webview显示的区域去显示

总结

以上就是针对 webview 设置圆角的方法,当然举一反三,其他的view也可以通过这样的方式设置圆角,具体实现根据具体需求来完成

猜你喜欢

转载自juejin.im/post/7033336643708780552