自定义圆形图片、圆角图片,椭圆图片

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhiwenyan/article/details/51803573

自定义圆形图片、圆角图片,椭圆图片,主要是利用BitmapShader (位图Shader)来进行图形填充;

先看效果图:
这里写图片描述

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="radius" format="dimension" />
    <attr name="type" format="integer" />


    <declare-styleable name="RoundView">
        <attr name="radius" />
        <attr name="type" />
    </declare-styleable>
</resources>

自定义了两个属性 :radius type 属性代表什么意思,往下看

RoundView:

package com.example.storm.ui;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ImageView;

/**
 * 自定义圆形图片
 */
public class RoundView extends ImageView {
    /**
     * 图片的类型,圆形、圆角、椭圆
     */
    private int type;
    public static final int TYPE_CIRCLE = 0;  //圆形
    public static final int TYPE_ROUND = 1;  //圆角
    public static final int TYPE_OVAL = 2;  //椭圆

    /**
     * 圆角大小的默认值
     */
    private static final int BODER_RADIUS_DEFAULT = 10;
    /**
     * 圆角的大小
     */
    private int mBorderRadius;
    /**
     * 绘图的Paint
     */
    private Paint mBitmapPaint;
    /**
     * 圆角的半径
     */
    private int mRadius;
    /**
     * 渲染图像,使用图像为绘制图形着色(图像填充)
     */
    private BitmapShader mBitmapShader;
    /**
     * view的宽度
     */
    private int mWidth;
    private RectF mRoundRect;

    public RoundView(Context context) {
        this(context, null);

    }

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

    public RoundView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mBitmapPaint = new Paint();
        mBitmapPaint.setAntiAlias(true);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundView);

        mBorderRadius = a.getDimensionPixelSize(R.styleable.RoundView_radius, (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, BODER_RADIUS_DEFAULT, getResources().getDisplayMetrics()));// 默认为10dp
        type = a.getInt(R.styleable.RoundView_type, TYPE_CIRCLE);// 默认圆形
        a.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        /**
         * 如果类型是圆形,需要改变view的宽高一致,以小值为准
         */
        if (type == TYPE_CIRCLE) {
            mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
            //半径
            mRadius = mWidth / 2;
            setMeasuredDimension(mWidth, mWidth);
        }
    }

    /**
     * 初始化BitmapShader
     */
    private void setUpShader() {
        Drawable drawable = getDrawable();
        if (drawable == null) {
            return;
        }
        Bitmap bmp = drawableToBitmap(drawable);
        // 将bmp作为着色器,就是在指定区域内绘制bmp
        mBitmapShader = new BitmapShader(bmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        // 设置shader,具有图像填充功能的画笔,利用此画笔在Canvas上绘制矩形、圆形、椭圆
        mBitmapPaint.setShader(mBitmapShader);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (getDrawable() == null) {
            return;
        }
        setUpShader();
        if (type == TYPE_ROUND) {
            //绘制圆角矩形
            canvas.drawRoundRect(mRoundRect, mBorderRadius, mBorderRadius, mBitmapPaint);
        } else if (type == TYPE_CIRCLE) {
             //绘制圆
            canvas.drawCircle(mRadius, mRadius, mRadius, mBitmapPaint);
        } else if (type == TYPE_OVAL) {
            //绘制一个矩形
            RectF rectF = new RectF(0, 0, getWidth(), getHeight());
            //在矩形内内切一个椭圆
            canvas.drawOval(rectF, mBitmapPaint);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // 圆角图片的范围
        if (type == TYPE_ROUND)
            mRoundRect = new RectF(0, 0, w, h);
    }

    /**
     * drawable转bitmap
     *
     * @param drawable
     * @return
     */
    private Bitmap drawableToBitmap(Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bd = (BitmapDrawable) drawable;
            return bd.getBitmap();
        }
        //取得Drawable的固有的宽度和高度
        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();
        Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        drawable.draw(canvas);
        return bitmap;
    }
}

xml 布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context="com.example.storm.ui.RxjavaActivity">

    <com.example.storm.ui.RoundView
        android:layout_width="wrap_content"
        android:layout_height="150dp"
        android:layout_gravity="center_horizontal"
        android:src="@mipmap/b"
        app:radius="60dp"
        app:type="0" />

    <com.example.storm.ui.RoundView
        android:layout_width="wrap_content"
        android:layout_height="150dp"
        android:layout_gravity="center_horizontal"
        android:src="@mipmap/b"
        app:radius="60dp"
        app:type="1" />

    <com.example.storm.ui.RoundView
        android:layout_width="wrap_content"
        android:layout_height="150dp"
        android:layout_gravity="center_horizontal"
        android:src="@mipmap/b"
        app:radius="60dp"
        app:type="2" />
</LinearLayout>

猜你喜欢

转载自blog.csdn.net/zhiwenyan/article/details/51803573