效果如下:
全部代码:【ShapeImageView】
package xiaodan.www.amor_love.Utils; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Path; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.provider.MediaStore; import android.util.AttributeSet; import xiaodan.www.amor_love.R; /** * 可设置形状的ImageView,抗边缘锯齿 * * @author 冯人唐 */ public class ShapeImageView extends android.support.v7.widget.AppCompatImageView { private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; private static final int COLORDRAWABLE_DIMENSION = 2; //系统数据库存放图片的路径 private static final Uri STORAGE_URI = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; public static int SHAPE_REC = 1; // 矩形 public static int SHAPE_CIRCLE = 2; // 圆形 public static int SHAPE_OVAL = 3; // 椭圆 private final Matrix mShaderMatrix = new Matrix(); private float mBorderSize = 0; // 边框大小,默认为0,即无边框 private int mBorderColor = Color.WHITE; // 边框颜色,默认为白色 private int mShape = SHAPE_REC; // 形状,默认为直接矩形 private float mRoundRadius = 0; // 矩形的圆角半径,默认为0,即直角矩形 private float mRoundRadiusLeftTop, mRoundRadiusLeftBottom, mRoundRadiusRightTop, mRoundRadiusRightBottom; private Paint mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private RectF mViewRect = new RectF(); // imageview的矩形区域 private RectF mBorderRect = new RectF(); // 边框的矩形区域 private Paint mBitmapPaint = new Paint(); private BitmapShader mBitmapShader; private Bitmap mBitmap; private Path mPath = new Path(); public ShapeImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ShapeImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // 虽然此处会调用setImageDrawable,但此时成员变量还未被正确初始化 init(attrs); mBorderPaint.setStyle(Style.STROKE); mBorderPaint.setStrokeWidth(mBorderSize); mBorderPaint.setColor(mBorderColor); mBorderPaint.setAntiAlias(true); mBitmapPaint.setAntiAlias(true); super.setScaleType(ScaleType.CENTER_CROP); // 固定为CENTER_CROP,其他不生效 } private void init(AttributeSet attrs) { TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ShapeImageView); mShape = a.getInt(R.styleable.ShapeImageView_siv_shape, mShape); mRoundRadius = a.getDimension(R.styleable.ShapeImageView_siv_round_radius, mRoundRadius); mBorderSize = a.getDimension(R.styleable.ShapeImageView_siv_border_size, mBorderSize); mBorderColor = a.getColor(R.styleable.ShapeImageView_siv_border_color, mBorderColor); mRoundRadiusLeftBottom = a.getDimension(R.styleable.ShapeImageView_siv_round_radius_leftBottom, mRoundRadius); mRoundRadiusLeftTop = a.getDimension(R.styleable.ShapeImageView_siv_round_radius_leftTop, mRoundRadius); mRoundRadiusRightBottom = a.getDimension(R.styleable.ShapeImageView_siv_round_radius_rightBottom, mRoundRadius); mRoundRadiusRightTop = a.getDimension(R.styleable.ShapeImageView_siv_round_radius_rightTop, mRoundRadius); a.recycle(); SelectorAttrs.obtainsAttrs(getContext(), this, attrs); } @Override public void setImageResource(int resId) { super.setImageResource(resId); mBitmap = getBitmapFromDrawable(getDrawable()); setupBitmapShader(); } public Bitmap getBitmapFromDrawable(Drawable drawable) { if (drawable == null) { return null; } if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } try { Bitmap bitmap; if (drawable instanceof ColorDrawable) { bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG); } else { bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG); } Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } catch (Exception e) { e.printStackTrace(); return null; } } private void setupBitmapShader() { // super(context, attrs, defStyle)调用setImageDrawable时,成员变量还未被正确初始化 if (mBitmapPaint == null) { return; } if (mBitmap == null) { invalidate(); return; } mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mBitmapPaint.setShader(mBitmapShader); // 固定为CENTER_CROP,使图片在view中居中并裁剪 mShaderMatrix.set(null); // 缩放到高或宽 与view的高或宽 匹配 float scale = Math.max(getWidth() * 1f / mBitmap.getWidth(), getHeight() * 1f / mBitmap.getHeight()); // 由于BitmapShader默认是从画布的左上角开始绘制,所以把其平移到画布中间,即居中 float dx = (getWidth() - mBitmap.getWidth() * scale) / 2; float dy = (getHeight() - mBitmap.getHeight() * scale) / 2; mShaderMatrix.setScale(scale, scale); mShaderMatrix.postTranslate(dx, dy); mBitmapShader.setLocalMatrix(mShaderMatrix); invalidate(); } @Override public void setImageDrawable(Drawable drawable) { super.setImageDrawable(drawable); mBitmap = getBitmapFromDrawable(drawable); setupBitmapShader(); } @Override public void setScaleType(ScaleType scaleType) { if (scaleType != ScaleType.CENTER_CROP) { throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType)); } } /** * 对于普通的view,在执行到onDraw()时,背景图已绘制完成 * <p> * 对于ViewGroup,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法, * 当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用, */ @Override public void onDraw(Canvas canvas) { if (mBitmap != null) { if (mShape == SHAPE_CIRCLE) { canvas.drawCircle(mViewRect.right / 2, mViewRect.bottom / 2, Math.min(mViewRect.right, mViewRect.bottom) / 2, mBitmapPaint); } else if (mShape == SHAPE_OVAL) { canvas.drawOval(mViewRect, mBitmapPaint); } else { // canvas.drawRoundRect(mViewRect, mRoundRadius, mRoundRadius, mBitmapPaint); mPath.reset(); mPath.addRoundRect(mViewRect, new float[]{ mRoundRadiusLeftTop, mRoundRadiusLeftTop, mRoundRadiusRightTop, mRoundRadiusRightTop, mRoundRadiusRightBottom, mRoundRadiusRightBottom, mRoundRadiusLeftBottom, mRoundRadiusLeftBottom, }, Path.Direction.CW); canvas.drawPath(mPath, mBitmapPaint); } } if (mBorderSize > 0) { // 绘制边框 if (mShape == SHAPE_CIRCLE) { canvas.drawCircle(mViewRect.right / 2, mViewRect.bottom / 2, Math.min(mViewRect.right, mViewRect.bottom) / 2 - mBorderSize / 2, mBorderPaint); } else if (mShape == SHAPE_OVAL) { canvas.drawOval(mBorderRect, mBorderPaint); } else { // canvas.drawRoundRect(mBorderRect, mRoundRadius, mRoundRadius, mBorderPaint); mPath.reset(); mPath.addRoundRect(mBorderRect, new float[]{ mRoundRadiusLeftTop, mRoundRadiusLeftTop, mRoundRadiusRightTop, mRoundRadiusRightTop, mRoundRadiusRightBottom, mRoundRadiusRightBottom, mRoundRadiusLeftBottom, mRoundRadiusLeftBottom, }, Path.Direction.CW); canvas.drawPath(mPath, mBorderPaint); } } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); initRect(); setupBitmapShader(); } // 不能在onLayout()调用invalidate(),否则导致绘制异常。(setupBitmapShader()中调用了invalidate()) @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); // initRect(); // setupBitmapShader(); } // 设置图片的绘制区域 private void initRect() { mViewRect.top = 0; mViewRect.left = 0; mViewRect.right = getWidth(); // 宽度 mViewRect.bottom = getHeight(); // 高度 // 边框的矩形区域不能等于ImageView的矩形区域,否则边框的宽度只显示了一半 mBorderRect.top = mBorderSize / 2; mBorderRect.left = mBorderSize / 2; mBorderRect.right = getWidth() - mBorderSize / 2; mBorderRect.bottom = getHeight() - mBorderSize / 2; } public int getShape() { return mShape; } public void setShape(int shape) { mShape = shape; } public float getBorderSize() { return mBorderSize; } public void setBorderSize(int mBorderSize) { this.mBorderSize = mBorderSize; mBorderPaint.setStrokeWidth(mBorderSize); initRect(); invalidate(); } public int getBorderColor() { return mBorderColor; } public void setBorderColor(int mBorderColor) { this.mBorderColor = mBorderColor; mBorderPaint.setColor(mBorderColor); invalidate(); } public float getRoundRadius() { return mRoundRadius; } public void setRoundRadius(float mRoundRadius) { this.mRoundRadius = mRoundRadius; invalidate(); } public void setRoundRadiis(float roundRadiusLeftBottom, float roundRadiusLeftTop, float roundRadiusRightBottom, float roundRadiusRightTop) { mRoundRadiusLeftBottom = roundRadiusLeftBottom; mRoundRadiusLeftTop = roundRadiusLeftTop; mRoundRadiusRightBottom = roundRadiusRightBottom; mRoundRadiusRightTop = roundRadiusRightTop; invalidate(); } public float[] getRoundRadiis() { return new float[]{mRoundRadiusLeftBottom, mRoundRadiusLeftTop, mRoundRadiusRightBottom, mRoundRadiusRightTop}; } }
工具类【SelectorAttrs】
package xiaodan.www.amor_love.Utils; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.LayerDrawable; import android.graphics.drawable.RippleDrawable; import android.graphics.drawable.StateListDrawable; import android.util.AttributeSet; import android.view.View; import xiaodan.www.amor_love.R; /** * 冯人唐 */ public class SelectorAttrs { public static final int RECTANGLE = 0; public static final int OVAL = 1; public static final int LINE = 2; public static final int RING = 3; /** * 直接在布局文件中直接设置selector * * @param context * @param view * @param attrs */ public static void obtainsAttrs(Context context, View view, AttributeSet attrs) { //背景已经设置为StateListDrawable\RippleDrawable,则不再设置Selector Drawable bitmapDrawable = view.getBackground(); if (bitmapDrawable instanceof StateListDrawable) { return; } if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { if (bitmapDrawable instanceof RippleDrawable) { return; } } TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.View); // 背景图片和背景颜色互斥,只能设置其中之一 if (bitmapDrawable instanceof ColorDrawable) { // 颜色值 bitmapDrawable = null; } // 用于设置背景的颜色和形状 GradientDrawable colorShapeDrawable = null; GradientDrawable colorShapeDrawablePressed = null; GradientDrawable colorShapeDrawableSelected = null; // 用于设置背景的图片 Drawable bitmapDrawablePressed = null; Drawable bitmapDrawableSelected = null; if (a.hasValue(R.styleable.View_sel_background_pressed) || a.hasValue(R.styleable.View_sel_background_border_pressed)) { bitmapDrawablePressed = a.getDrawable(R.styleable.View_sel_background_pressed); if (bitmapDrawablePressed instanceof ColorDrawable) { bitmapDrawablePressed = null; } if (bitmapDrawablePressed == null) { // 接下来设置背景颜色 colorShapeDrawablePressed = new GradientDrawable(); } } if (a.hasValue(R.styleable.View_sel_background_selected) || a.hasValue(R.styleable.View_sel_background_border_selected)) { bitmapDrawableSelected = a.getDrawable(R.styleable.View_sel_background_selected); if (bitmapDrawableSelected instanceof ColorDrawable) { bitmapDrawableSelected = null; } if (bitmapDrawableSelected == null) { colorShapeDrawableSelected = new GradientDrawable(); } } // 设置背景色 int background = Color.TRANSPARENT; if (bitmapDrawable == null) { Drawable bg = view.getBackground(); if (bg == null && a.hasValue(R.styleable.View_sel_background)) { // 兼容旧版本属性 bg = a.getDrawable(R.styleable.View_sel_background); } colorShapeDrawable = new GradientDrawable(); if (bg instanceof ColorDrawable) { background = ((ColorDrawable) bg).getColor(); colorShapeDrawable.setColor(background); } } if (colorShapeDrawablePressed != null) { colorShapeDrawablePressed.setColor(background); } if (colorShapeDrawableSelected != null) { colorShapeDrawableSelected.setColor(background); } // 形狀 int shape = a.getInt(R.styleable.View_sel_background_shape, RECTANGLE); if (shape == LINE) { if (colorShapeDrawable != null) { colorShapeDrawable.setShape(GradientDrawable.LINE); } if (colorShapeDrawablePressed != null) { colorShapeDrawablePressed.setShape(GradientDrawable.LINE); } if (colorShapeDrawableSelected != null) { colorShapeDrawableSelected.setShape(GradientDrawable.LINE); } } else if (shape == OVAL) { if (colorShapeDrawable != null) { colorShapeDrawable.setShape(GradientDrawable.OVAL); } if (colorShapeDrawablePressed != null) { colorShapeDrawablePressed.setShape(GradientDrawable.OVAL); } if (colorShapeDrawableSelected != null) { colorShapeDrawableSelected.setShape(GradientDrawable.OVAL); } } else if (shape == RING) { if (colorShapeDrawable != null) { colorShapeDrawable.setShape(GradientDrawable.RING); } if (colorShapeDrawablePressed != null) { colorShapeDrawablePressed.setShape(GradientDrawable.RING); } if (colorShapeDrawableSelected != null) { colorShapeDrawableSelected.setShape(GradientDrawable.RING); } } else { if (colorShapeDrawable != null) { colorShapeDrawable.setShape(GradientDrawable.RECTANGLE); } if (colorShapeDrawablePressed != null) { colorShapeDrawablePressed.setShape(GradientDrawable.RECTANGLE); } if (colorShapeDrawableSelected != null) { colorShapeDrawableSelected.setShape(GradientDrawable.RECTANGLE); } } // 圆角 int backgroundCorners = a.getDimensionPixelOffset(R.styleable.View_sel_background_corners, 0); final int radius = backgroundCorners; if (colorShapeDrawable != null) { colorShapeDrawable.setCornerRadius(backgroundCorners); } if (colorShapeDrawablePressed != null) { colorShapeDrawablePressed.setCornerRadius(backgroundCorners); } if (colorShapeDrawableSelected != null) { colorShapeDrawableSelected.setCornerRadius(backgroundCorners); } final int topLeftRadius = a.getDimensionPixelSize( R.styleable.View_sel_background_corner_topLeft, radius); final int topRightRadius = a.getDimensionPixelSize( R.styleable.View_sel_background_corner_topRight, radius); final int bottomLeftRadius = a.getDimensionPixelSize( R.styleable.View_sel_background_corner_bottomLeft, radius); final int bottomRightRadius = a.getDimensionPixelSize( R.styleable.View_sel_background_corner_bottomRight, radius); if (topLeftRadius != radius || topRightRadius != radius || bottomLeftRadius != radius || bottomRightRadius != radius) { if (colorShapeDrawable != null) { colorShapeDrawable.setCornerRadii(new float[]{ topLeftRadius, topLeftRadius, topRightRadius, topRightRadius, bottomRightRadius, bottomRightRadius, bottomLeftRadius, bottomLeftRadius }); } if (colorShapeDrawablePressed != null) { colorShapeDrawablePressed.setCornerRadii(new float[]{ topLeftRadius, topLeftRadius, topRightRadius, topRightRadius, bottomRightRadius, bottomRightRadius, bottomLeftRadius, bottomLeftRadius }); } if (colorShapeDrawableSelected != null) { colorShapeDrawableSelected.setCornerRadii(new float[]{ topLeftRadius, topLeftRadius, topRightRadius, topRightRadius, bottomRightRadius, bottomRightRadius, bottomLeftRadius, bottomLeftRadius }); } } // border int backgroundBorderWidth = a.getDimensionPixelOffset(R.styleable.View_sel_background_border_width, -1); if (backgroundBorderWidth != -1) { if (colorShapeDrawable != null) { colorShapeDrawable.setStroke(backgroundBorderWidth, 0); } if (colorShapeDrawablePressed != null) { colorShapeDrawablePressed.setStroke(backgroundBorderWidth, 0); } if (colorShapeDrawableSelected != null) { colorShapeDrawableSelected.setStroke(backgroundBorderWidth, 0); } } if (a.hasValue(R.styleable.View_sel_background_border_color)) { int backgroundBorder = a.getColor(R.styleable.View_sel_background_border_color, -1); if (colorShapeDrawable != null) { colorShapeDrawable.setStroke(backgroundBorderWidth, backgroundBorder); } if (colorShapeDrawablePressed != null) { colorShapeDrawablePressed.setStroke(backgroundBorderWidth, backgroundBorder); } if (colorShapeDrawableSelected != null) { colorShapeDrawableSelected.setStroke(backgroundBorderWidth, backgroundBorder); } } // 如果没有设置背景图片,则读取背景颜色 if (colorShapeDrawablePressed != null && a.hasValue(R.styleable.View_sel_background_pressed)) { int backgroundPressed = a.getColor(R.styleable.View_sel_background_pressed, 0); colorShapeDrawablePressed.setColor(backgroundPressed); } if (colorShapeDrawablePressed != null && a.hasValue(R.styleable.View_sel_background_border_pressed)) { int backgroundBorderPressed = a.getColor(R.styleable.View_sel_background_border_pressed, -1); colorShapeDrawablePressed.setStroke(backgroundBorderWidth, backgroundBorderPressed); } if (colorShapeDrawableSelected != null && a.hasValue(R.styleable.View_sel_background_selected)) { int backgroundSelected = a.getColor(R.styleable.View_sel_background_selected, -1); colorShapeDrawableSelected.setColor(backgroundSelected); } if (colorShapeDrawableSelected != null && a.hasValue(R.styleable.View_sel_background_border_selected)) { int backgroundBorderSelected = a.getColor(R.styleable.View_sel_background_border_selected, -1); colorShapeDrawableSelected.setStroke(backgroundBorderWidth, backgroundBorderSelected); } // 设置不同状态下的显示 StateListDrawable stateListDrawable = new StateListDrawable(); // ripple属性兼容低版本(<21) if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP // 低于21(5.0)版本 && a.hasValue(R.styleable.View_sel_background_ripple)) { // 但设置了ripple,处理兼容则把ripple的颜色设为按下时的颜色 Drawable drawable = null; if (a.hasValue(R.styleable.View_sel_background_ripple_mask)) { // 根据mask设置形状 drawable = a.getDrawable(R.styleable.View_sel_background_ripple_mask); if (drawable instanceof ColorDrawable) { // mask为颜色类型才可以设置形状 drawable = new GradientDrawable(); parseRippleMaskShape((GradientDrawable) drawable, a); // 以sel_background_ripple的颜色为准 ((GradientDrawable) drawable).setColor(a.getColor(R.styleable.View_sel_background_ripple, 0)); } else { drawable = a.getDrawable(R.styleable.View_sel_background_ripple); } } else { drawable = a.getDrawable(R.styleable.View_sel_background_ripple); } // ripple效果只是在原来的pressed基础上附加波纹效果,并不会单独作为pressed状态的效果 if (colorShapeDrawablePressed != null || bitmapDrawablePressed != null) { drawable = new LayerDrawable(new Drawable[]{ bitmapDrawablePressed != null ? bitmapDrawablePressed : colorShapeDrawablePressed, drawable }); } else if (bitmapDrawable != null || colorShapeDrawable != null) { drawable = new LayerDrawable(new Drawable[]{ bitmapDrawable != null ? bitmapDrawable : colorShapeDrawable, drawable }); } stateListDrawable.addState( new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed}, drawable); } else if (colorShapeDrawablePressed != null || bitmapDrawablePressed != null) { Drawable drawable = bitmapDrawablePressed != null ? bitmapDrawablePressed : colorShapeDrawablePressed; stateListDrawable.addState( new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed}, drawable); } if (colorShapeDrawableSelected != null || bitmapDrawableSelected != null) { Drawable drawable = bitmapDrawableSelected != null ? bitmapDrawableSelected : colorShapeDrawableSelected; stateListDrawable.addState( new int[]{android.R.attr.state_enabled, android.R.attr.state_selected}, drawable); } stateListDrawable.addState( new int[]{}, bitmapDrawable != null ? bitmapDrawable : colorShapeDrawable); // 设置ripple水波纹 boolean hasRipple = parseRipple(view, a, // ripple效果只是在原来的pressed基础上附加波纹效果,并不会单独作为pressed状态的效果 (colorShapeDrawable != null || bitmapDrawable != null || colorShapeDrawablePressed != null || bitmapDrawablePressed != null) ? stateListDrawable : null); if (!hasRipple) { view.setBackgroundDrawable(stateListDrawable); } a.recycle(); } private static void parseRippleMaskShape(GradientDrawable maskShapeDrawable, TypedArray a) { // 必须设置颜色 maskShapeDrawable.setColor(a.getColor(R.styleable.View_sel_background_ripple_mask, Color.TRANSPARENT)); // Mask形状 int shape = a.getInt(R.styleable.View_sel_background_ripple_mask_shape, RECTANGLE); if (shape == LINE) { maskShapeDrawable.setShape(GradientDrawable.LINE); } else if (shape == OVAL) { maskShapeDrawable.setShape(GradientDrawable.OVAL); } else if (shape == RING) { maskShapeDrawable.setShape(GradientDrawable.RING); } else { maskShapeDrawable.setShape(GradientDrawable.RECTANGLE); } // mask圆角 int backgroundCorners = a.getDimensionPixelOffset(R.styleable.View_sel_background_ripple_mask_corners, 0); final int radius = backgroundCorners; maskShapeDrawable.setCornerRadius(backgroundCorners); final int topLeftRadius = a.getDimensionPixelSize( R.styleable.View_sel_background_ripple_mask_corner_topLeft, radius); final int topRightRadius = a.getDimensionPixelSize( R.styleable.View_sel_background_ripple_mask_corner_topRight, radius); final int bottomLeftRadius = a.getDimensionPixelSize( R.styleable.View_sel_background_ripple_mask_corner_bottomLeft, radius); final int bottomRightRadius = a.getDimensionPixelSize( R.styleable.View_sel_background_ripple_mask_corner_bottomRight, radius); if (topLeftRadius != radius || topRightRadius != radius || bottomLeftRadius != radius || bottomRightRadius != radius) { maskShapeDrawable.setCornerRadii(new float[]{ topLeftRadius, topLeftRadius, topRightRadius, topRightRadius, bottomRightRadius, bottomRightRadius, bottomLeftRadius, bottomLeftRadius }); } } private static boolean parseRipple(View view, TypedArray a, Drawable content) { // 设置ripple水波纹 boolean hasRipple = false; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { if (a.hasValue(R.styleable.View_sel_background_ripple)) { hasRipple = true; // 设置了背景则作为ripple的contentDrawable // 用于设置mask的形状 GradientDrawable maskShapeDrawable = null; // 用于设置mask的图片 Drawable maskBitmapDrawable = null; if (a.hasValue(R.styleable.View_sel_background_ripple_mask)) { maskBitmapDrawable = a.getDrawable(R.styleable.View_sel_background_ripple_mask); if (maskBitmapDrawable instanceof ColorDrawable) { maskBitmapDrawable = null; } if (maskBitmapDrawable == null) { // 接下来设置mask形状 maskShapeDrawable = new GradientDrawable(); parseRippleMaskShape(maskShapeDrawable, a); } } RippleDrawable rippleDrawable = new RippleDrawable( a.getColorStateList(R.styleable.View_sel_background_ripple), content, maskBitmapDrawable != null ? maskBitmapDrawable : maskShapeDrawable); view.setBackgroundDrawable(rippleDrawable); } } return hasRipple; } }
之后在values的文件夹下面新建“attrs.xml”文件:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="ShapeImageView"> <attr name="siv_shape" format="enum"> <enum name="rect" value="1" /> <enum name="circle" value="2" /> <enum name="oval" value="3" /> </attr> <attr name="siv_round_radius" format="dimension" /> <attr name="siv_round_radius_leftTop" format="dimension" /> <attr name="siv_round_radius_leftBottom" format="dimension" /> <attr name="siv_round_radius_rightTop" format="dimension" /> <attr name="siv_round_radius_rightBottom" format="dimension" /> <attr name="siv_border_size" format="dimension" /> <attr name="siv_border_color" format="color" /> </declare-styleable> <!-- 设置view相关selector熟悉--> <declare-styleable name="View"> <attr name="injectListener" format="boolean" /> <!--该属性已过时,被废弃--> <attr name="sel_background" format="color" /> <!-- 背景状态 --> <attr name="sel_background_pressed" format="reference|color" /> <attr name="sel_background_selected" format="reference|color" /> <!-- 背景形状 --> <attr name="sel_background_shape" format="enum"> <enum name="rect" value="0" /> <enum name="oval" value="1" /> <enum name="line" value="2" /> <enum name="ring" value="3" /> </attr> <!-- 背景圆角 --> <attr name="sel_background_corners" format="dimension" /> <attr name="sel_background_corner_topLeft" format="dimension" /> <attr name="sel_background_corner_topRight" format="dimension" /> <attr name="sel_background_corner_bottomLeft" format="dimension" /> <attr name="sel_background_corner_bottomRight" format="dimension" /> <!-- 背景边框默认状态 --> <attr name="sel_background_border_color" format="color" /> <attr name="sel_background_border_width" format="dimension" /> <!-- 背景边框状态 --> <attr name="sel_background_border_pressed" format="color" /> <attr name="sel_background_border_selected" format="color" /> <!-- ripple水波纹效果--> <attr name="sel_background_ripple" format="reference|color" /> <attr name="sel_background_ripple_mask" format="reference|color" /> <!-- ripple mask形状(仅在sel_background_ripple_mask为color时生效)--> <attr name="sel_background_ripple_mask_shape" format="enum"> <enum name="rect" value="0" /> <enum name="oval" value="1" /> <enum name="line" value="2" /> <enum name="ring" value="3" /> </attr> <!-- ripple mask圆角 --> <attr name="sel_background_ripple_mask_corners" format="dimension" /> <attr name="sel_background_ripple_mask_corner_topLeft" format="dimension" /> <attr name="sel_background_ripple_mask_corner_topRight" format="dimension" /> <attr name="sel_background_ripple_mask_corner_bottomLeft" format="dimension" /> <attr name="sel_background_ripple_mask_corner_bottomRight" format="dimension" /> </declare-styleable> </resources>大功告成,可以在布局里面用了