android 滴滴司机接单滑动按钮,笔记20171127-Android仿滴滴呼叫车时转圈圈的View

需求:

类似滴滴打车,呼叫车,但是司机还未接单,等待计时的自定义View

要达到的效果:

8e03a3540d07

转圈圈.jpeg

用hongyang大神的自定义View教程中的思路实现的

相关代码:

1.attrs.xml(这个文件里放的是自定义view的属性)

2.自定义的View 我给它起名叫CircleView(反正就是个圆)

package weekimwee.cn.circleviewdemo;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.RectF;

import android.support.annotation.Nullable;

import android.util.AttributeSet;

import android.util.TypedValue;

import android.view.View;

import java.math.BigDecimal;

import java.text.SimpleDateFormat;

/**

* Created by Wee Kim Wee on 2017/10/23.

*/

public class CircleView extends View {

private int firstColor;

private int secondColor;

private int circleWidth;

private int speed;

private int textSize;

private float progress;

private boolean isNext;

private String bigCircleText;

private int bigCircleTextColor;

private int time;

private DrawThread drawThread;

private SimpleDateFormat formatter = new SimpleDateFormat("mm分ss秒");

private final String LOADING ="已等待";

private Paint paint;

public CircleView(Context context) {

this(context,null);

}

public CircleView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs,0);

}

public CircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.circle, defStyleAttr, 0);

int n = a.getIndexCount();

for(int i = 0; i < n; i++){

int attr = a.getIndex(i);

switch (attr){

case R.styleable.circle_firstColor:

firstColor = a.getColor(attr, Color.GRAY);

break;

case R.styleable.circle_secondColor:

secondColor = a.getColor(attr,Color.GRAY);

break;

case R.styleable.circle_circleWidth:

circleWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(

TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics()));

break;

case R.styleable.circle_speed:

speed=a.getInt(attr, 20);

break;

case R.styleable.circle_textSize:

textSize =a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(

TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));

break;

case R.styleable.circle_textColorFirst:

bigCircleTextColor = a.getColor(attr,Color.BLACK);

break;

}

}

a.recycle();

bigCircleText = "00分00秒";

paint = new Paint();

drawThread = new DrawThread();

drawThread.start();

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//大圆

int centre = getWidth() / 2; // 获取圆心的x坐标

int radius = (centre - circleWidth / 2)-25;// 半径

paint.setStrokeWidth(circleWidth); // 设置圆环的宽度

paint.setAntiAlias(true); // 消除锯齿

paint.setStyle(Paint.Style.STROKE); // 设置空心

RectF oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius); // 用于定义的圆弧的形状和大小的界限

//跟着跑的小圆

float h = (float) (2*( Math.PI / 360) * progress);

float x = (float) ( radius+25+Math.sin(h) * radius);

float y = (float) (radius+25-Math.cos(h) * radius);

//在180度位置上的圆

//float hc = (float) (2*( Math.PI / 360) * 180);

//float xc = (float) ( radius+25+Math.sin(hc) * radius);

//float yc = (float) (radius+25-Math.cos(hc) * radius);

//大圆边框绘制颜色

if (!isNext) {// 第一颜色的圈完整,第二颜色跑

paint.setColor(firstColor); // 设置圆环的颜色

canvas.drawCircle(centre, centre, radius, paint); // 画出圆环

paint.setColor(secondColor); // 设置圆环的颜色

canvas.drawArc(oval, -90, progress, false, paint); // 根据进度画圆弧

paint.setColor(secondColor);

paint.setStyle(Paint.Style.FILL);

canvas.drawCircle(x,y,10,paint);

//paint.setColor(firstColor);

//paint.setStyle(Paint.Style.FILL);

//canvas.drawCircle(xc,yc,10,paint);

} else {

paint.setColor(secondColor); // 设置圆环的颜色

canvas.drawCircle(centre, centre, radius, paint); // 画出圆环

paint.setColor(firstColor); // 设置圆环的颜色

canvas.drawArc(oval, -90, progress, false, paint); // 根据进度画圆弧

paint.setColor(firstColor);

paint.setStyle(Paint.Style.FILL);

canvas.drawCircle(x,y,8,paint);

//paint.setColor(secondColor);

//paint.setStyle(Paint.Style.FILL);

//canvas.drawCircle(xc,yc,10,paint);

}

paint.setTextSize(textSize);

//已等待

float loadingTextWidth = paint.measureText(LOADING);

paint.setColor(Color.GRAY);

paint.setStrokeWidth(1);

canvas.drawText(LOADING,centre-loadingTextWidth/2,centre-textSize,paint);

//几分几秒

float bigCircleTextWidth = paint.measureText(bigCircleText);

paint.setColor(bigCircleTextColor);

canvas.drawText(bigCircleText, centre - bigCircleTextWidth / 2, centre + textSize , paint);

}

public void stop(){

drawThread.close();

}

class DrawThread extends Thread {

private boolean isRun = true;

@Override

public void run() {

while (isRun) {

BigDecimal b1 = new BigDecimal(Float.toString(progress));

BigDecimal b2 = new BigDecimal(Float.toString(0.3f));

progress = b1.add(b2).floatValue();

if (progress == 360) {

progress = 0;

if (!isNext)

isNext = true;

else

isNext = false;

}

time = time+speed;

postInvalidate();

bigCircleText = formatter.format(time);

try {

Thread.sleep(speed);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

public void close() {

isRun = false;

}

}

}

3.activity_main.xml布局中使用上述View

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="weekimwee.cn.circleviewdemo.MainActivity">

android:layout_alignParentTop="true"

android:padding="20dp"

android:id="@+id/helloworld"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Hello World!" />

android:id="@+id/view"

android:layout_centerInParent="true"

android:layout_width="200dp"

android:layout_height="200dp"

app:firstColor="#ff4500"

app:secondColor="#d3d3d3"

app:circleWidth="2dp"

app:speed="25"

app:textSize="20sp"

app:textColorFirst ="#ff4500"

app:textColorSecond="#d3d3d3"

/>

4.MainActivity.java中使用View开始计时

package weekimwee.cn.circleviewdemo

import android.support.v7.app.AppCompatActivity

import android.os.Bundle

import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

helloworld.setOnClickListener {

view.stop()

}

}

}

实现思路:

必要条件:

空心大圆,两种颜色

实心的小圆,也是两种颜色

计时线程,30秒小圆要绕着大圆走一圈并更换颜色,大圆中间的text显示计时

具体代码中的实现:

在构造方法中把属性获取下来

计时的线程开始启动,线程中的逻辑:

360度的大圆,每25毫秒转0.3f度,转1200次刚好转完,刚好30秒(因为我没有用动画,直接是在View中重绘的,如果是3度这样的,会显的一卡一卡的不平滑)

onDraw方法:

(1)先画大圆(大圆位置是固定的)

(2)计算小圆的位置(每次重绘角度已经变了,所以要重新计算小圆的位置)

(3)大圆边框绘制颜色,以及绘制小圆(小圆颜色与大圆边框一致)

(4)绘制大圆中间的字

stop方法

这个方法供外部调用停止计时线程,例如呼叫到车了,这个页面finish了之类的

以上是这个呼叫车计时等待View的笔记,demo在这里在这里!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值