Android 自定义View 路径跑马灯
此篇文章所记载内容为项目种遇到的难点
可以看见图片红框部份为渐变并且可以由左至右循环移动
如果使用一个 paint ,那么只有当 光条 完全移动到最右侧时才能重新回到最左侧;
解决方法:
初始化两个paint
下文第一个 paint 称为 A;第二个paint称为B;
不管A还是B 都有头部跟尾部
思路
当A的尾部到达最右侧时,让B的尾部从最左端开始向右移动
当A的头部到达最右侧时,让B的头部从最左端开始向右移动
当B的尾部到达最右侧时,让A的尾部从最左端开始向右移动
当B的头部到达最右侧时,让A的头部从最左端开始向右移动
就是一个这样的循环就可以完成
代码
自定义View代码
public class MainTopView extends View {
private Rect mRect, mRectSolid,mRect1;
private Paint mPaint, mPaintSolid,mPaint1;
private int x = 0, x1 = 0,x2 = 0, x3 = 0;
public MainTop(Context context) {
this(context, null);
}
public void start(int x, int x1, int x2, int x3) {
this.x = x;
this.x1 = x1;
this.x2 = x2;
this.x3 = x3;
invalidate();
}
public MainTop(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MainTop(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mRect = new Rect();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mRect1 = new Rect();
mPaint1 = new Paint();
mPaint1.setAntiAlias(true);
mRectSolid = new Rect();
mPaintSolid = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(2f);
mPaint1.setStyle(Paint.Style.STROKE);
mPaint1.setStrokeWidth(2f);
mPaintSolid.setColor(Color.parseColor("#FF043A60"));
mPaintSolid.setStyle(Paint.Style.STROKE);
mPaintSolid.setStrokeWidth(1f);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
LinearGradient linearGradient = new LinearGradient(this.x, 0, this.x1, 0, new int[]{
Color.parseColor("#00043A60"),
Color.parseColor("#FF35BCFF"),
Color.parseColor("#00043A60")},
new float[]{0, 0.5F, 1}, Shader.TileMode.CLAMP);
mPaint.setShader(linearGradient);
LinearGradient linearGradient1 = new LinearGradient(this.x2, 0, this.x3, 0, new int[]{
Color.parseColor("#00043A60"),
Color.parseColor("#FF35BCFF"),
Color.parseColor("#00043A60")},
new float[]{0, 0.5F, 1}, Shader.TileMode.CLAMP);
mPaint1.setShader(linearGradient1);
Path path = new Path();
path.lineTo(0, 15);
path.lineTo(470, 15);
path.lineTo(505, 0);
path.lineTo(1450, 0);
path.lineTo(1485, 15);
path.rLineTo(1920, 15);
canvas.drawPath(path, mPaintSolid);
canvas.drawPath(path, mPaint);
canvas.drawPath(path, mPaint1);
}
}
使用时在activity中定义四个int 以及 四个boolean
boolean 跟 int 一一对应,为true时将对应的int +=1,为false时 = 0
if (flag) {
i += 1;
} else {
i = 0;
}
if (flag1) {
i1 += 1;
} else {
i1 = 0;
}
if (flag2) {
i2 += 1;
} else {
i2 = 0;
}
if (flag3) {
i3 += 1;
} else {
i3 = 0;
}
再判断 四个int 分别是否达到最右侧 (屏幕最右侧也就是屏幕的宽度)通过WindowManager获取
if (i1 == mWidth){
flag3 = true;
}else if(i == mWidth){
flag2 = true;
flag = false;
flag1 = false;
}else if(i3 == mWidth){
flag1 = true;
}else if(i2 == mWidth){
flag = true;
flag2 = false;
flag3 = false;
}
效果图
速度可自己调整
此做法并不是最好,B或者(非A第一次)出现时 应该从屏幕左侧外移动进来而非让尾部增长,后续会更新。
各位大神有优化方法评论区见,