package demo.pplive.com.imagepoint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.CountDownTimer; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.animation.AlphaAnimation; /** * @Createdby : jixiongxu * @on :2017/10/31 * @description :显示进度条的视频预览,用户在选择快进的时候显示出快进的点的视频截图 * @problem 目前存在的问题是内存一直在抖动,现在尚未解决,希望在真是使用过程将图片压缩后可以解决 */ public class ImagePointView extends View { private static final String TAG = "ImagePointView"; // 最大X长度 private static final int MAX_X = 200; // 最大Y长度 private static final int MAX_Y = 120; // 最小X长度 private static final int MIN_X = 50; // 最小Y长度 private static final int MIN_Y = 30; // scaleType 16:9 public static final int SCALETYPE_W16_H9 = 1; // scaleType 4:3 public static final int SCALETYPE_W4_H3 = 0; // 默認padding private static final int defaultPadding = 3; private float density; // 图片地址 private String mUrl; // 需要画的图片 private Bitmap mSrc; // 默认的图片 private Bitmap mDefaultSrc; // 宽度 private int width; // 高度 private int height; // 下边三角形的高度 private int angleHeight = 5; // 16:9 private float W16_H9_SCALE = 1.77777f; // 4:3 private float W4_H3_SCALE = 1.33333f; // 0表示4:3,1表示16:9 private int mScaleType = SCALETYPE_W16_H9; private int mPadding = defaultPadding; // 是测量用的,为了避免内存抖动drawableToBitmap private int w; // 是测量用的,为了避免内存抖动drawableToBitmap private int h; // 是测量用的,为了避免内存抖动drawableToBitmap private Bitmap bitmap; // 是测量用的,为了避免内存抖动drawableToBitmap private Bitmap.Config config; // 是测量用的,为了避免内存抖动drawableToBitmap private Canvas canvas; private Context mContext; // 倒计时,为了自动消失 private CountDownTimer timer; private Paint mBackGroundPaint = new Paint(); private Paint mImagePaint = new Paint(); private Paint mAnglePaint = new Paint(); private Rect size = new Rect(); private Path mPath = new Path(); private AlphaAnimation alpha = new AlphaAnimation(1.0f, 0f); public ImagePointView(Context context) { super(context); mContext = context; initView(); } public ImagePointView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public ImagePointView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } private void initView() { alpha.setDuration(2000); alpha.setFillAfter(true); } // 3秒后开始消失,消失时间是2秒 private void autoDismiss() { if (timer != null) { try { timer.cancel(); timer.start(); } catch (Exception e) { e.printStackTrace(); } } else { timer = new CountDownTimer(5000, 1000) { @Override public void onTick(long l) { if (l < 2000) { setAnimation(); } } @Override public void onFinish() { dismiss(); } }; timer.start(); } } private void recycle() { } public void setAnimation() { this.startAnimation(alpha); } public void dismiss() { if (this.getVisibility() != GONE) { this.setVisibility(GONE); } } private void show() { if (this.getVisibility() != VISIBLE) { Log.d("jixiongxu", "show"); this.setVisibility(VISIBLE); } } // 预留接口 public void setUrl(String url) { if (url == null || url.isEmpty()) { return; } mUrl = url; } // 预留接口 public void setDefaultPadding(int padding) { mPadding = padding; } public void setScaleType(int type) { mScaleType = type; } public void setBitmap(Bitmap src) { if (src == null) { return; } mSrc = src; invalidate(); show(); autoDismiss(); } public void setDefaultSrc(Bitmap def) { if (def == null) { return; } mDefaultSrc = def; } // 预留接口 private Bitmap drawableToBitmap(Drawable drawable) { // 取 drawable 的长宽 w = drawable.getIntrinsicWidth(); h = drawable.getIntrinsicHeight(); // 取 drawable 的颜色格式 config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; // 建立对应 bitmap bitmap = Bitmap.createBitmap(w, h, config); // 建立对应 bitmap 的画布 canvas = new Canvas(bitmap); drawable.setBounds(0, 0, w, h); // 把 drawable 内容画到画布中s drawable.draw(canvas); return bitmap; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int mWidth = MeasureSpec.getSize(widthMeasureSpec); int mHeight = MeasureSpec.getSize(heightMeasureSpec); Log.d("TAG", "" + mWidth); Log.d("TAG", "" + mHeight); density = getResources().getDisplayMetrics().density; if (mWidth > MAX_X) { width = MAX_X; } if (mWidth < MIN_X) { width = MIN_X; } if (mHeight > MAX_Y) { height = MAX_Y; } if (mHeight < MIN_Y) { mHeight = MIN_Y; } mPadding = (int) (density * defaultPadding); // 缩放标准 w = (int) Math.min(width * density, mWidth); h = (int) Math.min(height * density, mHeight); int scaleTemp = Math.min(w, h); if (mScaleType == SCALETYPE_W16_H9) { if (scaleTemp == w) { width = scaleTemp; height = (int) (scaleTemp / W16_H9_SCALE); } else if (scaleTemp == h) { height = scaleTemp; width = (int) (scaleTemp * W16_H9_SCALE); } } else if (mScaleType == SCALETYPE_W4_H3) { if (scaleTemp == w) { width = scaleTemp; height = (int) (scaleTemp / W4_H3_SCALE); } else if (scaleTemp == h) { height = scaleTemp; width = (int) (scaleTemp * W4_H3_SCALE); } } size.set(mPadding, mPadding, width - mPadding, height - mPadding); setMeasuredDimension(width, (int) (height + angleHeight * density)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); DrawBackGround(canvas); DrawImage(canvas); DrawAngle(canvas); } // 先画背景 private void DrawBackGround(Canvas canvas) { // 画笔 mBackGroundPaint.setColor(Color.WHITE); mBackGroundPaint.setStyle(Paint.Style.FILL); canvas.drawRect(0, 0, width, height, mBackGroundPaint); } // 再画图片 private void DrawImage(Canvas canvas) { // 画笔 mImagePaint.setStyle(Paint.Style.FILL); if (mSrc != null) { canvas.drawBitmap(mSrc, null, size, mImagePaint); } else { Log.e(TAG, "image is null"); if (mDefaultSrc != null) { canvas.drawBitmap(mDefaultSrc, null, size, mImagePaint); } else { Log.e(TAG, "default image is null"); } } } // 最后画三角形 private void DrawAngle(Canvas canvas) { mAnglePaint.setStyle(Paint.Style.FILL); // 全透明外框 mAnglePaint.setColor(Color.argb(0, 0, 0, 0)); canvas.drawRect(0, height, width, (int) (height + angleHeight * density), mAnglePaint); mAnglePaint.setStyle(Paint.Style.FILL); mAnglePaint.setColor(Color.WHITE); // 下面的三角形 mPath.moveTo(width / 2 - angleHeight * density, height); mPath.lineTo(width / 2 + angleHeight * density, height); mPath.lineTo(width / 2, height + angleHeight * density); mPath.close(); canvas.drawPath(mPath, mAnglePaint); } @Override public void dispatchWindowVisibilityChanged(int visibility) { super.dispatchWindowVisibilityChanged(visibility); if (visibility == GONE) { // dosomething } else if (visibility == VISIBLE) { // dosomething } } }
//效果图