自定义圆形、圆角矩形View

来源:互联网 发布:php网页代码 编辑:程序博客网 时间:2024/06/09 22:10

简介

日常开发中经常要用到圆角矩形或者圆形来显示头像或图片,因此对于它的使用方式我们还是比较关注的。下面我们就自定义一个View来进行圆角矩形或圆形图片的展示,同时也支持自定义设置边框大小、边框颜色、按下状态蒙层颜色等属性。

效果图

使用

1、在attrs.xml中自定义属性

<declare-styleable name="RoundImageView">    <!-- 显示类型 -->    <attr name="imageType" format="enum">        <enum name="circle" value="0" />        <enum name="round" value="1" />    </attr>    <!-- 边框大小 -->    <attr name="borderWidth" format="dimension" />    <!-- 边框颜色 -->    <attr name="borderColor" format="color" />    <!-- 圆角大小 -->    <attr name="roundRadius" format="dimension" />    <!-- 按下状态蒙层颜色 -->    <attr name="coverColor" format="color" />    <!-- 是否可被按下 -->    <attr name="isPressed" format="boolean" /></declare-styleable>

2、布局引用

 <LinearLayout    android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center"    android:orientation="vertical">    <com.wiggins.roundpicture.widget.RoundImageView        android:layout_width="100dp"        android:layout_height="100dp"        android:src="@drawable/pic_one" />    <com.wiggins.roundpicture.widget.RoundImageView        android:layout_width="100dp"        android:layout_height="100dp"        android:layout_marginBottom="@dimen/margin_large"        android:layout_marginTop="@dimen/margin_large"        android:src="@drawable/pic_three"        app:borderColor="@color/red"        app:borderWidth="1.5dp"        app:imageType="circle" />    <com.wiggins.roundpicture.widget.RoundImageView        android:layout_width="100dp"        android:layout_height="100dp"        android:src="@drawable/pic_two"        app:borderColor="@color/colorAccent"        app:borderWidth="1.5dp"        app:imageType="round" /></LinearLayout>

3、自定义RoundImageView

初始化属性

private void initAttributes() {    // 设置缩放    setScaleType(ScaleType.CENTER_CROP);    // 初始化画笔等属性    mShaderMatrix = new Matrix();    mRcBitmap = new RectF();    mRcBorder = new RectF();    mBitmapPaint = new Paint();    mBitmapPaint.setAntiAlias(true);    mBitmapPaint.setDither(true);    mBorderPaint = new Paint();    mBorderPaint.setAntiAlias(true);    mBorderPaint.setDither(true);    mBorderPaint.setStyle(Paint.Style.FILL);    mBorderPaint.setColor(mBorderColor);    mBorderPaint.setStrokeWidth(mBorderWidth);}

渲染器及大小

private void setShader() {    Drawable drawable = getDrawable();    if (drawable == null) {        return;    }    Bitmap bitmap = getBitmapFromDrawable(drawable);    mBitmapShader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);    mBitmapPaint.setShader(mBitmapShader);    mRcBorder.set(0, 0, getWidth(), getHeight());    mBorderRadius = Math.min((mRcBorder.height() - mBorderWidth) / 2, (mRcBorder.width() - mBorderWidth) / 2);    if (mImageType == TYPE_CIRCLE) {        mRcBitmap.set(mBorderWidth, mBorderWidth, mRcBorder.width() - mBorderWidth, mRcBorder.height() - mBorderWidth);    } else if (mImageType == TYPE_ROUND) {        mRcBitmap.set(mBorderWidth / 2, mBorderWidth / 2, mRcBorder.width() - mBorderWidth / 2, mRcBorder.height() - mBorderWidth / 2);    }    mBitmapRadius = Math.min(mRcBitmap.height() / 2, mRcBitmap.width() / 2);    updateShaderMatrix(bitmap);    invalidate();}

矩阵变换

private void updateShaderMatrix(Bitmap mBitmap) {    float scale;    float dx = 0;    float dy = 0;    mShaderMatrix.set(null);    if (mBitmap.getWidth() * mRcBitmap.height() > mRcBitmap.width() * mBitmap.getHeight()) {        scale = mRcBitmap.height() / (float) mBitmap.getHeight();        dx = (mRcBitmap.width() - mBitmap.getWidth() * scale) * 0.5f;    } else {        scale = mRcBitmap.width() / (float) mBitmap.getWidth();        dy = (mRcBitmap.height() - mBitmap.getHeight() * scale) * 0.5f;    }    mShaderMatrix.setScale(scale, scale);    mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth);    mBitmapShader.setLocalMatrix(mShaderMatrix);}

视图绘制

@Overrideprotected void onDraw(Canvas canvas) {    if (getDrawable() == null) {        return;    }    setShader();    if (mImageType == TYPE_ROUND) {        canvas.drawRoundRect(mRcBorder, mRoundRadius, mRoundRadius, mBorderPaint);        canvas.drawRoundRect(mRcBitmap, mRoundRadius, mRoundRadius, mBitmapPaint);    } else {        canvas.drawCircle(mCenterCoordinates, mCenterCoordinates, mBorderRadius, mBorderPaint);        canvas.drawCircle(mCenterCoordinates, mCenterCoordinates, mBitmapRadius, mBitmapPaint);    }}

触屏事件

@Overridepublic boolean onTouchEvent(MotionEvent event) {    int action = event.getActionMasked();    switch (action) {        case MotionEvent.ACTION_DOWN:            setPressed(true);            break;        case MotionEvent.ACTION_MOVE:            if (!mRcBitmap.contains(event.getX(), event.getY())) {                setPressed(false);            }            break;        case MotionEvent.ACTION_UP:        case MotionEvent.ACTION_CANCEL:            setPressed(false);            break;    }    return true;}

按下状态蒙层颜色

@Overridepublic void setPressed(boolean pressed) {    super.setPressed(pressed);    if (!mIsPressed) {        return;    }    if (pressed) {        mBitmapPaint.setColorFilter(new PorterDuffColorFilter(mCoverColor, PorterDuff.Mode.SRC_ATOP));    } else {        mBitmapPaint.setColorFilter(null);    }    invalidate();}

项目地址 ☞ 传送门