先上目的图
先画矩形 由于这么这个效果要求啊 我决定用Path ,如果要问为什么的话,那当直觉吧
先是画笔准备
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(stroke_width);
mPaint.setColor(Color.BLACK);
然后是准备宽高 ,这里由于不能直接在onDraw 里边操作,所以直接放进 要写的宽高转换一下就行了
//放入事先的宽高
int x=dip2px(context,300);
int y=dip2px(context,100);
public int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
Path 规划路径,这里用二阶贝塞尔给他一个 圆角的 感觉
path = new Path();
path.moveTo(x,y/2);
path.lineTo(x, radiuRightTop);
path.quadTo(x,0,x-radiuRightTop,0);
path.lineTo(radiuRightTop,0);
path.quadTo(0,0,0,radiuRightTop);
path.lineTo(0,y/2);
path2 = new Path();
path2.moveTo(0,y/2);
path2.lineTo(0, y-radiuRightTop);
path2.quadTo(0,y,radiuRightTop,y);
path2.lineTo(x-radiuRightTop,y);
path2.quadTo(x,y,x,y-radiuRightTop);
path2.lineTo(x,y/2);
canvas.drawPath(path,mPaint);
canvas.drawPath(path2,mPaint);
这里可以明显的 到 圆角位置的 线比较粗
这里也是 问了几个大群,一顿的不耻下问
终于找到问题了,线宽问题:
这里的 圆角宽度实际上是 原始宽度,正确的宽度,一开始并没有考虑到线宽问题,现在重新修改一下 左边,就一个道理
在不影响 线的长度的情况下,修改宽度,也就是 X轴固定死 那就修改Y,Y轴固定死 那就修改X,总之你来回试吧,心诚则灵
path.moveTo(x - stk_er, y / 2);
path.lineTo(x - stk_er, radiuRightTop);
path.quadTo(x, 0, x - radiuRightTop, 0 + stk_er);
path.lineTo(radiuRightTop, 0 + stk_er);
path.quadTo(0, 0, 0 + stk_er, radiuRightTop);
path.lineTo(0 + stk_er, y / 2);
path2 = new Path();
path2.moveTo(0 + stk_er, y / 2);
path2.lineTo(0 + stk_er, y - radiuRightTop);
path2.quadTo(0, y, radiuRightTop, y - stk_er);
path2.lineTo(x - radiuRightTop, y - stk_er);
path2.quadTo(x, y, x - stk_er, y - radiuRightTop);
path2.lineTo(x - stk_er, y / 2);
stk_er 是线宽的一半
然后就是让他动起来,需要用到PathMeasure 了
完整代码
public class MyLinearLayout extends LinearLayout {
private final float stroke_width=10;
private float stk_er;
private Paint mPaint;
private Path mDst,mDst2;
private int radiuRightTop=60;
private float mLength,mLength2;
private float mAnimatorValue;
private PathMeasure mPathMeasure,mPathMeasure2;
private boolean flag=true;
private Bitmap bmp;
private Path path;
private Path path2;
public MyLinearLayout(Context context) {
this(context, null);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
stk_er=stroke_width/2;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(stroke_width);
mPaint.setColor(Color.BLACK);
// 得到原始的图片
// int x = getWidth();
// int y = getHeight();
//放入事先的宽高
int x=dip2px(context,300);
int y=dip2px(context,100);
path = new Path();
path.moveTo(x-stk_er,y/2);
path.lineTo(x-stk_er, radiuRightTop);
path.quadTo(x,0,x-radiuRightTop,0+stk_er);
path.lineTo(radiuRightTop,0+stk_er);
path.quadTo(0,0,0+stk_er,radiuRightTop);
path.lineTo(0+stk_er,y/2);
path2 = new Path();
path2.moveTo(0+stk_er,y/2);
path2.lineTo(0+stk_er, y-radiuRightTop);
path2.quadTo(0,y,radiuRightTop,y-stk_er);
path2.lineTo(x-radiuRightTop,y-stk_er);
path2.quadTo(x,y,x-stk_er,y-radiuRightTop);
path2.lineTo(x-stk_er,y/2);
mPathMeasure = new PathMeasure();
mPathMeasure.setPath(path, false);
mLength = mPathMeasure.getLength();
mDst=new Path();
mPathMeasure2 = new PathMeasure();
mPathMeasure2.setPath(path2, false);
mLength2 = mPathMeasure2.getLength();
mDst2=new Path();
final ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mAnimatorValue = (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
valueAnimator.setDuration(2000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.start();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onDraw(Canvas canvas) {
// canvas.drawPath(path,mPaint);
// canvas.drawPath(path2,mPaint);
mDst.reset();
float stop = mLength * mAnimatorValue;
float start = (float) (stop - ((0.5 - Math.abs(mAnimatorValue - 0.5)) * mLength));
mPathMeasure.getSegment(start, stop, mDst, true);
canvas.drawPath(mDst, mPaint);
mDst2.reset();
float stop2 = mLength2 * mAnimatorValue;
float start2 = (float) (stop2 - ((0.5 - Math.abs(mAnimatorValue - 0.5)) * mLength2));
mPathMeasure2.getSegment(start2, stop2, mDst2, true);
canvas.drawPath(mDst2, mPaint);
// if(flag){
//
// flag=false;
// }
}
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
XML 预先设定的宽高一致300 100
有个小坑啊 ,必须设置背景色 不然你会发现 啥也木有啊 ...
https://www.jianshu.com/p/3efa5341abcc 留个眼 这个效果没做出来 goPosTan
public class MyLinearLayout extends LinearLayout {
private Paint mPaint;
private Path path;
private PathMeasure mPathMeasure;
private float mAnimatorValue;
private float mLength;
private float[] pos;
private float[] tan;
private Bitmap bitmap;
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.RED);
mPaint.setStrokeWidth(5);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setAntiAlias(true);
path = new Path();
path.moveTo(0, 0);
path.quadTo(100, 200, 200, 0);
path.quadTo(300, -200, 400, 0);
mPathMeasure = new PathMeasure(path, false);
mLength = mPathMeasure.getLength();
pos = new float[2];
tan = new float[2];
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.boat);
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(5000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mAnimatorValue = (float) animation.getAnimatedValue();
postInvalidate();
}
});
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.start();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.translate(200, 400);
canvas.drawPath(path, mPaint);
mPathMeasure.getPosTan(mLength * mAnimatorValue, pos, tan);
float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI);
canvas.rotate(degrees, pos[0], pos[1]);
float left = pos[0] - bitmap.getWidth() / 2;
float top = pos[1] - bitmap.getHeight() / 2;
// float top = pos[1] - bitmap.getHeight() ;// 不除2会始终悬浮在 线上 俩种效果可以看一下
canvas.drawBitmap(bitmap, left, top, mPaint);
canvas.restore();
}
}
是时候 粘贴了
mPathMeasure.getPosTan(mLength * mAnimatorValue, pos, tan);
pos[]代表的就是当前的XY坐标
一开始 船只能显示一般 以为呢 这个和上面那个不太一样,上面那个是MatchParent
这个是固定死的 所以要在 X,Y 的坐标上进行修改 和上面那个 stk_er 一个道理
最后的Path
path.moveTo(x - stk_er-50, y / 2);
path.lineTo(x - stk_er-50, radiuRightTop);
path.quadTo(x-50, 0+50, x-50 - radiuRightTop, 0 + stk_er+50);
path.lineTo(radiuRightTop+50, 0 + stk_er+50);
path.quadTo(0+50, 0+50, 0 + stk_er+50, radiuRightTop);
path.lineTo(0 + stk_er+50, y / 2);
把俩个都改一下
path2 = new Path();
path2.moveTo(0 + stk_er + margin, y / 2);
path2.lineTo(0 + stk_er + margin, y - radiuRightTop);
path2.quadTo(0 + margin, y - margin, radiuRightTop + margin, y - stk_er - margin);
path2.lineTo(x - radiuRightTop - margin, y - stk_er - margin);
path2.quadTo(x - margin, y - margin, x - stk_er - margin, y - radiuRightTop);
path2.lineTo(x - stk_er - margin, y / 2);
这里我们一定是需要用到俩个画布 进行操作的
所以这里涉及到一个概念问题关于画布的 ,https://blog.csdn.net/toplist/article/details/6588278
找了很久最后得到一个模糊的结论 就是 new Canvas(bitmap),确保你的bitmap 是 可以被当做画布的,
可以这么写
//android不允许直接修改res里面的图片,所以要用copy方法
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher).copy(Bitmap.Config.ARGB_8888,true);
Canvas mCanvas = new Canvas(bitmap);
方法二 也是 比较常用的
bitmapCanvas = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);
canvas2 = new Canvas(bitmapCanvas);
这里一个 重要概念 你用newCanvas 画完之后,一定要用
正牌的canvas ,在画一下
canvas.drawBitmap(bitmapCanvas, 0, 0, null);
这里可以看出,canvas 只是一个 对bitmap 进行操作的 临时工具,所以最后还是要把它的 bitmap 画出来
public class MyLinearLayout extends View {
private final float stroke_width = 10;
private final int margin = 50;
private float stk_er;
private Paint mPaint;
private int radiuRightTop = 100;
private float mLength, mLength2;
private float mAnimatorValue;
private PathMeasure mPathMeasure, mPathMeasure2;
private Bitmap bitmap;
private Path path;
private Path path2;
private float[] pos;
private float[] tan;
private float[] pos1;
private float[] tan1;
private Canvas canvas2;
private Bitmap bitmapCanvas;
private int x;
private int y;
public MyLinearLayout(Context context) {
this(context, null);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
stk_er = stroke_width / 2;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(stroke_width);
mPaint.setColor(Color.BLACK);
// 得到原始的图片
// int x = getWidth();
// int y = getHeight();
//放入事先的宽高
x = dip2px(context, 300);
y = dip2px(context, 100);
path = new Path();
path.moveTo(x - stk_er - margin, y / 2);
path.lineTo(x - stk_er - margin, radiuRightTop);
path.quadTo(x - margin, 0 + margin, x - margin - radiuRightTop, 0 + stk_er + margin);
path.lineTo(radiuRightTop + margin, 0 + stk_er + margin);
path.quadTo(0 + margin, 0 + margin, 0 + stk_er + margin, radiuRightTop);
path.lineTo(0 + stk_er + margin, y / 2);
path2 = new Path();
path2.moveTo(0 + stk_er + margin, y / 2);
path2.lineTo(0 + stk_er + margin, y - radiuRightTop);
path2.quadTo(0 + margin, y - margin, radiuRightTop + margin, y - stk_er - margin);
path2.lineTo(x - radiuRightTop - margin, y - stk_er - margin);
path2.quadTo(x - margin, y - margin, x - stk_er - margin, y - radiuRightTop);
path2.lineTo(x - stk_er - margin, y / 2);
mPathMeasure = new PathMeasure();
mPathMeasure.setPath(path, false);
mLength = mPathMeasure.getLength();
mPathMeasure2 = new PathMeasure();
mPathMeasure2.setPath(path2, false);
mLength2 = mPathMeasure2.getLength();
final ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mAnimatorValue = (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
valueAnimator.setDuration(2000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
// valueAnimator.start();
pos = new float[2];
tan = new float[2];
pos1 = new float[2];
tan1 = new float[2];
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.boat);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// canvas.save();
canvas.translate(0, 0);
canvas.drawPath(path, mPaint);
mPathMeasure.getPosTan(mLength * mAnimatorValue, pos, tan);
float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI);
canvas.rotate(degrees, pos[0], pos[1]);
float left = pos[0] - bitmap.getWidth() / 2;
float top = pos[1] - bitmap.getHeight() / 2;
// float top = pos[1] - bitmap.getHeight() ;// 不除2会始终悬浮在 线上 俩种效果可以看一下
canvas.drawBitmap(bitmap, left, top, mPaint);
// canvas.restore();
bitmapCanvas = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);
canvas2 = new Canvas(bitmapCanvas);
// canvas2.save();
canvas2.translate(0, 0);
canvas2.drawPath(path2, mPaint);
mPathMeasure2.getPosTan(mLength2 * mAnimatorValue, pos1, tan1);
float degrees2 = (float) (Math.atan2(tan1[1], tan1[0]) * 180.0 / Math.PI);
canvas2.rotate(degrees2, pos1[0], pos1[1]);
float left1 = pos1[0] - bitmap.getWidth() / 2;
float top1 = pos1[1] - bitmap.getHeight() / 2;
// float top = pos[1] - bitmap.getHeight() ;// 不除2会始终悬浮在 线上 俩种效果可以看一下
canvas2.drawBitmap(bitmap, left1, top1, mPaint);
canvas.drawBitmap(bitmapCanvas, 0, 0, null);
// canvas2.restore();
}
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
做一下修改
多虑了 直接注释去掉就可以
package com.as.demo_touch;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.LinearLayout;
/**
* -----------------------------
* Created by zqf on 2019/9/2.
* ---------------------------
*/
public class MyLinearLayout extends View {
private final float stroke_width = 10;
private final int margin = 50;
private float stk_er;
private Paint mPaint;
private int radiuRightTop = 100;
private float mLength, mLength2;
private float mAnimatorValue;
private PathMeasure mPathMeasure, mPathMeasure2;
private Bitmap bitmap;
private Path path;
private Path path2;
private float[] pos;
private float[] tan;
private float[] pos1;
private float[] tan1;
private Canvas canvas2;
private Bitmap bitmapCanvas;
private int x;
private int y;
public MyLinearLayout(Context context) {
this(context, null);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
stk_er = stroke_width / 2;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(stroke_width);
mPaint.setColor(Color.BLACK);
// 得到原始的图片
// int x = getWidth();
// int y = getHeight();
//放入事先的宽高
x = dip2px(context, 300);
y = dip2px(context, 100);
path = new Path();
path.moveTo(x - stk_er - margin, y / 2);
path.lineTo(x - stk_er - margin, radiuRightTop);
path.quadTo(x - margin, 0 + margin, x - margin - radiuRightTop, 0 + stk_er + margin);
path.lineTo(radiuRightTop + margin, 0 + stk_er + margin);
path.quadTo(0 + margin, 0 + margin, 0 + stk_er + margin, radiuRightTop);
path.lineTo(0 + stk_er + margin, y / 2);
path2 = new Path();
path2.moveTo(0 + stk_er + margin, y / 2);
path2.lineTo(0 + stk_er + margin, y - radiuRightTop);
path2.quadTo(0 + margin, y - margin, radiuRightTop + margin, y - stk_er - margin);
path2.lineTo(x - radiuRightTop - margin, y - stk_er - margin);
path2.quadTo(x - margin, y - margin, x - stk_er - margin, y - radiuRightTop);
path2.lineTo(x - stk_er - margin, y / 2);
mPathMeasure = new PathMeasure();
mPathMeasure.setPath(path, false);
mLength = mPathMeasure.getLength();
mPathMeasure2 = new PathMeasure();
mPathMeasure2.setPath(path2, false);
mLength2 = mPathMeasure2.getLength();
final ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mAnimatorValue = (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
valueAnimator.setDuration(2000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.start();
pos = new float[2];
tan = new float[2];
pos1 = new float[2];
tan1 = new float[2];
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.boat);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.translate(0, 0);
canvas.drawPath(path, mPaint);
mPathMeasure.getPosTan(mLength * mAnimatorValue, pos, tan);
float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI);
canvas.rotate(degrees, pos[0], pos[1]);
float left = pos[0] - bitmap.getWidth() / 2;
float top = pos[1] - bitmap.getHeight() / 2;
// float top = pos[1] - bitmap.getHeight() ;// 不除2会始终悬浮在 线上 俩种效果可以看一下
canvas.drawBitmap(bitmap, left, top, mPaint);
canvas.restore();
bitmapCanvas = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);
canvas2 = new Canvas(bitmapCanvas);
canvas2.save();
canvas2.translate(0, 0);
canvas2.drawPath(path2, mPaint);
mPathMeasure2.getPosTan(mLength2 * mAnimatorValue, pos1, tan1);
float degrees2 = (float) (Math.atan2(tan1[1], tan1[0]) * 180.0 / Math.PI);
canvas2.rotate(degrees2, pos1[0], pos1[1]);
float left1 = pos1[0] - bitmap.getWidth() / 2;
float top1 = pos1[1] - bitmap.getHeight() / 2;
// float top = pos[1] - bitmap.getHeight() ;// 不除2会始终悬浮在 线上 俩种效果可以看一下
canvas2.drawBitmap(bitmap, left1, top1, mPaint);
canvas.drawBitmap(bitmapCanvas, 0, 0, null);
canvas2.restore();
}
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
在做修改,把画图 改为画线
canvas.save();
canvas.translate(0, 0);
mPaint.setColor(Color.BLACK);
canvas.drawPath(path, mPaint);
mPathMeasure.getPosTan(mLength * mAnimatorValue, pos, tan);
float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI);
canvas.rotate(degrees, pos[0], pos[1]);
float left = pos[0] - bitmap.getWidth() / 2;
float top = pos[1] - bitmap.getHeight() / 2;
// float top = pos[1] - bitmap.getHeight() ;// 不除2会始终悬浮在 线上 俩种效果可以看一下
mPaint.setColor(Color.RED);
canvas.drawLine(pos[0], pos[1], left, top, mPaint);
canvas.restore();
bitmapCanvas = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);
canvas2 = new Canvas(bitmapCanvas);
canvas2.save();
canvas2.translate(0, 0);
mPaint.setColor(Color.BLACK);
canvas2.drawPath(path2, mPaint);
mPathMeasure2.getPosTan(mLength2 * mAnimatorValue, pos1, tan1);
float degrees2 = (float) (Math.atan2(tan1[1], tan1[0]) * 180.0 / Math.PI);
canvas2.rotate(degrees2, pos1[0], pos1[1]);
float left1 = pos1[0] - bitmap.getWidth() / 2;
float top1 = pos1[1] - bitmap.getHeight() / 2;
// float top = pos[1] - bitmap.getHeight() ;// 不除2会始终悬浮在 线上 俩种效果可以看一下
mPaint.setColor(Color.RED);
canvas2.drawLine(pos1[0], pos1[1], left1, top1, mPaint);
canvas.drawBitmap(bitmapCanvas, 0, 0, null);
canvas2.restore();
线的方向不对先改方向,最后发现 这个实现方案不行~ 太难了 ,,等找到解决方法再补上吧 ,先找个图顶上
public class MyLinearLayout extends View {
private final float stroke_width = 6;
private final int margin = 26;
private float stk_er;
private Paint mPaint;
private int radiuRightTop = 100;
private float mLength, mLength2;
private float mAnimatorValue;
private PathMeasure mPathMeasure, mPathMeasure2;
private Bitmap bitmap;
private Path path;
private Path path2;
private float[] pos;
private float[] tan;
private float[] pos1;
private float[] tan1;
private Canvas canvas2;
private Bitmap bitmapCanvas;
private int x;
private int y;
public MyLinearLayout(Context context) {
this(context, null);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
stk_er = stroke_width / 2;
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(stroke_width);
mPaint.setColor(Color.WHITE);
// 得到原始的图片
// int x = getWidth();
// int y = getHeight();
//放入事先的宽高
x = dip2px(context, 300);
y = dip2px(context, 100);
path = new Path();
path.moveTo(x - stk_er - margin, y / 2);
path.lineTo(x - stk_er - margin, radiuRightTop);
path.quadTo(x - margin, 0 + margin, x - margin - radiuRightTop, 0 + stk_er + margin);
path.lineTo(radiuRightTop + margin, 0 + stk_er + margin);
path.quadTo(0 + margin, 0 + margin, 0 + stk_er + margin, radiuRightTop);
path.lineTo(0 + stk_er + margin, y / 2);
path2 = new Path();
path2.moveTo(0 + stk_er + margin, y / 2);
path2.lineTo(0 + stk_er + margin, y - radiuRightTop);
path2.quadTo(0 + margin, y - margin, radiuRightTop + margin, y - stk_er - margin);
path2.lineTo(x - radiuRightTop - margin, y - stk_er - margin);
path2.quadTo(x - margin, y - margin, x - stk_er - margin, y - radiuRightTop);
path2.lineTo(x - stk_er - margin, y / 2);
mPathMeasure = new PathMeasure();
mPathMeasure.setPath(path, false);
mLength = mPathMeasure.getLength();
mPathMeasure2 = new PathMeasure();
mPathMeasure2.setPath(path2, false);
mLength2 = mPathMeasure2.getLength();
final ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mAnimatorValue = (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
valueAnimator.setDuration(2000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.start();
pos = new float[2];
tan = new float[2];
pos1 = new float[2];
tan1 = new float[2];
ImageView imageView = new ImageView(context);
imageView.setImageResource(R.drawable.line);
// imageView.setDrawingCacheEnabled(true);
// bitmap = Bitmap.createBitmap(imageView.getDrawingCache());
// imageView.setDrawingCacheEnabled(false);
// imageView.setBackground(context.getResources().getDrawable(R.drawable.line));
//
// Drawable shape = getResources().getDrawable(R.drawable.line);
// bitmap = Bitmap.createBitmap(shape.getIntrinsicWidth(),
// shape.getIntrinsicHeight(),
// shape.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
//
// Canvas canvas = new Canvas(bitmap);
// shape.setBounds(0, 0, shape.getIntrinsicWidth(), shape.getIntrinsicHeight());
// shape.draw(canvas);
// bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.linexxxx);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.translate(0, 0);
canvas.drawPath(path, mPaint);
mPathMeasure.getPosTan(mLength * mAnimatorValue, pos, tan);
float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI);
canvas.rotate(degrees, pos[0], pos[1]);
float left = pos[0] - bitmap.getWidth() / 2;
float top = pos[1] - bitmap.getHeight() / 2;
// float top = pos[1] - bitmap.getHeight() ;// 不除2会始终悬浮在 线上 俩种效果可以看一下
canvas.drawBitmap(bitmap, left, top, mPaint);
canvas.restore();
bitmapCanvas = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);
canvas2 = new Canvas(bitmapCanvas);
canvas2.save();
canvas2.translate(0, 0);
canvas2.drawPath(path2, mPaint);
mPathMeasure2.getPosTan(mLength2 * mAnimatorValue, pos1, tan1);
float degrees2 = (float) (Math.atan2(tan1[1], tan1[0]) * 180.0 / Math.PI);
canvas2.rotate(degrees2, pos1[0], pos1[1]);
float left1 = pos1[0] - bitmap.getWidth() / 2;
float top1 = pos1[1] - bitmap.getHeight() / 2;
// float top = pos[1] - bitmap.getHeight() ;// 不除2会始终悬浮在 线上 俩种效果可以看一下
canvas2.drawBitmap(bitmap, left1, top1, mPaint);
canvas.drawBitmap(bitmapCanvas, 0, 0, null);
canvas2.restore();
}
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
这里呢 有关那个小图 我是先用Shape 画出来 然后在 截图 ,开画图 改了一下 像素