点击打开链接
代码:
自定义属性 :
values/attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CustomImageView"> <attr name="leftTopX" format="float" /> <attr name="leftTopY" format="float" /> <attr name="rightTopX" format="float" /> <attr name="rightTopY" format="float" /> <attr name="rightBottomX" format="float" /> <attr name="rightBottomY" format="float" /> <attr name="leftBottomX" format="float" /> <attr name="leftBottomY" format="float" /> <attr name="roundPx" format="float"/> </declare-styleable> </resources>
代码部分:
package com.example.he.customimageview; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.support.annotation.NonNull; import android.util.AttributeSet; import android.util.Log; import android.view.animation.LinearInterpolator; import android.widget.ImageView; /** * Created by he on 2017/3/11. */ public class CustomImageView extends ImageView { private final String TAG = getClass().getSimpleName(); private Paint mPaint; private Path mPath; private Drawable drawable; //控件在指定为wrap_content下的默认宽高 private static final int DEFAULT_WIDTH = 500; private static final int DEFAULT_HEIGHT = 300; private float leftTopX; private float leftTopY; private float rightTopX; private float rightTopY; private float rightBottomX; private float rightBottomY; private float leftBottomX; private float leftBottomY; private float roundPx; private int dx; private int dy; public CustomImageView(Context context) { this(context, null); } public CustomImageView(Context context, AttributeSet attrs) { super(context, attrs); mPaint = new Paint(); mPath = new Path(); mPaint.setAntiAlias(true); mPaint.setColor(Color.WHITE); drawable = getDrawable(); setWillNotDraw(false); obtainStyledAttributes(attrs); setImageResource(R.drawable.transparent); } /** * 获取自定义属性 * * @param attrs */ private void obtainStyledAttributes(AttributeSet attrs) { final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CustomImageView); leftTopX = a.getFloat(R.styleable.CustomImageView_leftTopX, 10f); leftTopY = a.getFloat(R.styleable.CustomImageView_leftTopY, 15f); rightTopX = a.getFloat(R.styleable.CustomImageView_rightTopX, 10f); rightTopY = a.getFloat(R.styleable.CustomImageView_rightTopY, 15f); rightBottomX = a.getFloat(R.styleable.CustomImageView_rightBottomX, 10f); rightBottomY = a.getFloat(R.styleable.CustomImageView_rightBottomY, 15f); leftBottomX = a.getFloat(R.styleable.CustomImageView_leftBottomX, 10f); leftBottomY = a.getFloat(R.styleable.CustomImageView_leftBottomY, 15f); roundPx = a.getFloat(R.styleable.CustomImageView_roundPx, 0f); a.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) { setMeasuredDimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } else if (widthMode == MeasureSpec.AT_MOST) { setMeasuredDimension(DEFAULT_WIDTH, heightSize); } else if (heightMode == MeasureSpec.AT_MOST) { Log.d(TAG, "onMeasure: " + widthSize); setMeasuredDimension(widthSize, DEFAULT_HEIGHT); } else { setMeasuredDimension(widthSize, heightSize); } } @Override protected void onDraw(Canvas canvas) { if (drawable == null) { super.onDraw(canvas); return; } Bitmap b = ((BitmapDrawable) drawable).getBitmap(); RectF rectF = new RectF(dx, dy, getWidth() - dx, getHeight() - dy); //清屏 // canvas.drawColor(Color.BLUE, PorterDuff.Mode.CLEAR); // Paint p=new Paint(); // p.setColor(Color.WHITE); // canvas.drawPaint(p); canvas.drawARGB(0, 0, 0, 0); int layId = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG); final Rect rectSrc = new Rect(0, 0, b.getWidth(), b.getHeight()); final Rect rectDst = new Rect(0, 0, getWidth(), getHeight()); if (roundPx > 0f) { canvas.drawRoundRect(rectF, roundPx, roundPx, mPaint); } else { float radii[] = {leftTopX, leftTopY, rightTopX, rightTopY, rightBottomX, rightBottomY, leftBottomX, leftBottomY}; mPath.addRoundRect(rectF, radii, Path.Direction.CCW); canvas.drawPath(mPath, mPaint); } mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(b, rectSrc, rectDst, mPaint); mPaint.setXfermode(null); canvas.restoreToCount(layId); } public void clipX(int start, int end, long duration) { ValueAnimator animator = ValueAnimator.ofInt(start, end); animator.setDuration(duration); animator.setInterpolator(new LinearInterpolator()); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { dx = (int) animation.getAnimatedValue(); postInvalidate(); } }); animator.start(); } public void clipY(int start, int end, long duration) { ValueAnimator animator = ValueAnimator.ofInt(start, end); animator.setDuration(duration); animator.setInterpolator(new LinearInterpolator()); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { dy = (int) animation.getAnimatedValue(); postInvalidate(); } }); animator.start(); } public static int dp2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } // /** // * 绘制圆角矩形图片 // */ // @Override // protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); // if (drawable!=null) { // Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); // Bitmap b = getRoundBitmap(bitmap); // final Rect rectSrc = new Rect(0, 0, b.getWidth(), b.getHeight()); // final Rect rectDst = new Rect(0, 0, getWidth(), getHeight()); // mPaint.reset(); // canvas.drawBitmap(b, rectSrc, rectDst, mPaint); // // } else { // super.onDraw(canvas); // } // } /** * 获取圆角矩形图片 * * @param bitmap * @param * @return Bitmap */ private Bitmap getRoundBitmap(@NonNull Bitmap bitmap) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); mPaint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); mPaint.setColor(color); Path path = new Path(); if (roundPx > 0f) { canvas.drawRoundRect(rectF, roundPx, roundPx, mPaint); Log.d(TAG, "getRoundBitmap: "); } else { // float radii[] = {400, 400, 400, 450, 400, 450, 400, 450}; float radii[] = {leftTopX, leftTopY, rightTopX, rightTopY, rightBottomX, rightBottomY, leftBottomX, leftBottomY}; path.addRoundRect(rectF, radii, Path.Direction.CCW); canvas.drawPath(path, mPaint); } mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, mPaint); return output; } } MainActivity: package com.example.he.customimageview; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private int width; private int height; private CustomImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView = (CustomImageView) findViewById(R.id.ima); Button clipX = (Button) findViewById(R.id.clipX); Button clipY = (Button) findViewById(R.id.clipY); Button recoverX = (Button) findViewById(R.id.recoverX); Button recoverY = (Button) findViewById(R.id.recoverY); clipX.setOnClickListener(this); clipY.setOnClickListener(this); recoverX.setOnClickListener(this); recoverY.setOnClickListener(this); width = CustomImageView.dp2px(this, 200); height = CustomImageView.dp2px(this, 100); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.clipX: //从左右两边同时裁剪,裁剪掉宽度的2/3(左边裁1/3,右边裁1/3) imageView.clipX(0, width / 3, 5000); break; case R.id.clipY: //从上下两边同时裁剪,裁剪掉高度的2/3(上边裁1/3,下边裁1/3) imageView.clipY(0, height / 3, 5000); break; case R.id.recoverX: imageView.clipX(width / 3, 0, 4000); break; case R.id.recoverY: imageView.clipY(height / 3, 0, 5000); break; default: break; } } }如果觉得还可以求个Star