Android -自定义外卖订单流程

最近在做项目的时候,有个功能是订单流程每个阶段的时间段,这个和购物或者外卖的时候的下单、接单、配送类似!请看下图这里写图片描述

刚开始的做的时候,没有想过自定义还是按照之前的想法,ui作图根据状态替换图片之类的,后面做着做着感觉好烦,而且这个为了以后方便人调用之类的,所以开始自定义封装!

分析:
1:总共有五个状态,已支付、已接单、等待配送、已签收、待评价

这五个点根据屏幕五等分,每个圆心按照比例相加画大空心圆和小的实心圆。

2:画实线和虚线,根据五等分的比例算出每两个相邻的圆之间的x

长度,左右两边分别加2和减2(留出缝隙处理),这样就可以画出

实线和虚线(实线和虚线根据数据来处理)虚线处理稍微复杂一点,见代码注解

3:现在画时间和状态,这里需要居中处理,刚开始的没有处理,导致字体和圆心没有垂直居中!具体的处理的方法代码有明确说明

给出自定义类:

package org.yidont.ylife.send.view;


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

import org.yidont.ylife.send.R;
import org.yidont.ylife.send.bean.OrderStatusDescribeInfo;

import java.util.ArrayList;
import java.util.List;


/**
 * Created by li4236 on 16/6/21.
 * li4236@aliyun.com
 */
public class CustomRoundTrue extends View {


    private final Paint paint;
    private final Context context;

    public CustomRoundTrue(Context context) {

        // TODO Auto-generated constructor stub
        this(context, null);
    }

    public CustomRoundTrue(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        this.context = context;
        this.paint = new Paint();
        this.paint.setAntiAlias(true); //消除锯齿
        this.paint.setStyle(Paint.Style.FILL); //绘制空心圆
    }

//    int number = 5;

    int radius = 30;//圆的半径

    int vivio = 4;//控制显示多少个实心圆

//    int state = 2;//控制底部文字显示

    float mFloat[];

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        //平分控件的高度,每段的高度

        radius = dip2px(15);
        int height =getHeight() / 2;

        //平分宽度十等分
        int width = getWidth() / (5 * 2);

        //画虚线的设置start///

        int cc = 2 * width - 2 * radius - 4;//计算虚线或者实线的宽度 ,-4是因为左右两边圆各自留出2的距离 查看99和100行

        mFloat = new float[cc / 2];

        for (int i = 0; i < cc / 2; i++) {
            mFloat[i] = 3;//虚线的宽度初始化
        }

        //画虚线的大小end///


        //1 画最上层的圆///start//
        int circleY = height - radius - radius / 2;

        for (int i = 0; i < mornal.size(); i++) {

            OrderStatusDescribeInfo info = mornal.get(i);

            int circleX = width + i * 2 * width;
            this.paint.setARGB(255, 153, 153, 153);
            this.paint.setStrokeWidth(2);

            if (info.getStatus().equals("0")) { //画虚圆

                canvas.drawCircle(circleX, circleY, radius, this.paint);
            } else { //画实圆
                drawReal(circleX, circleY, canvas);
            }


        }


        boolean really = false;
        for (int j = 0; j < mornal.size()-1; j++) { //画线

            really = true;

            int n = j+1;
            if (n < mornal.size())
            {
                OrderStatusDescribeInfo info1 = mornal.get(n);
                if (info1.getStatus().equals("0"))//获取下一个数据是空的
                    really = false;
            }

            int lineX = width + j * 2 * width + radius + 2; //+2是为了留出缝隙
            int lineX1 = (width + j * 2 * width) + 2 * width - radius - 2;//-2是为了留出缝隙

            if (!really) { //画虚线

                Paint paint = new Paint();
                paint.setStyle(Paint.Style.STROKE);
                paint.setColor(Color.DKGRAY);
                Path path = new Path();
                path.moveTo(lineX, circleY);//起点 x/y
                path.lineTo(lineX1, circleY);//终点 x/y
                PathEffect effects = new DashPathEffect(mFloat, 1);//虚线数组
                paint.setPathEffect(effects);
                canvas.drawPath(path, paint);

            } else {//画实线

                this.paint.setARGB(255, 255, 108, 0);
                canvas.drawLine(lineX, circleY, lineX1, circleY, paint);
            }


        }


        //1 画最上层的圆///end//

        //2 画最下层的文字///start//


        int txtY = height + radius;//第一行文字的Y高度

        Paint mPaintLines = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintLines.setStrokeWidth(3);
        mPaintLines.setTextSize(dip2px(14));
        mPaintLines.setTextAlign(Paint.Align.LEFT);

        Rect rect = new Rect();

        for (int i = 0; i < mornal.size(); i++) {

            OrderStatusDescribeInfo info = mornal.get(i);

            int lineX = width + i * 2 * width;//每个字符串x坐标

            mPaintLines.getTextBounds(info.getText(), 0, 1, rect);//可以获取字体宽高

            float awayY2 = txtY + rect.height() + radius / 2;//底层文字y高度计算


            if (info.getStatus().equals("1")) {//需要显示的时间和文字

                //画时间
                mPaintLines.setColor(getResources().getColor(R.color.send_time));

                mPaintLines.getTextBounds(info.getTime(), 0, info.getTime().length(), rect);
                canvas.drawText(info.getTime(), lineX - rect.width() / 2, txtY, mPaintLines);

                //画送货的状态
                mPaintLines.setColor(getResources().getColor(R.color.send_state));
                mPaintLines.getTextBounds(info.getText(), 0, info.getText().length(), rect);
                canvas.drawText(info.getText(), lineX - rect.width() / 2, awayY2, mPaintLines);

            } else {

                //单个送货的状态
                mPaintLines.setColor(getResources().getColor(R.color.send_state_gray));
                mPaintLines.getTextBounds(info.getText(), 0, info.getText().length(), rect);
                canvas.drawText(info.getText(), lineX - rect.width() / 2, awayY2, mPaintLines);

//                //单个送货的状态    ======= 居中显示
//                mPaintLines.setColor(getResources().getColor(R.color.send_state_gray));
//                mPaintLines.getTextBounds(info.getText(), 0, info.getText().length(), rect);
//
//                float awayY = awayY2 / 2 + height / 2 + rect.height() / 2;//设置字体垂直居中计算高度
//                canvas.drawText(info.getText(), lineX - rect.width() / 2, awayY, mPaintLines);

            }

        }


        //2 画最下层的文字///end//

        super.onDraw(canvas);
    }


    public void drawReal(int x, int y, Canvas canvas) {
//        绘制外圆
        this.paint.setARGB(255, 255, 108, 0);
        this.paint.setStrokeWidth(2);
        canvas.drawCircle(x, y, radius, this.paint);


        //绘制圆环
        this.paint.setColor(Color.WHITE);
//        this.paint.setStrokeWidth(ringWidth);
        canvas.drawCircle(x, y, radius - 3, this.paint);


        //绘制内圆
        this.paint.setARGB(255, 255, 108, 0);
        this.paint.setStrokeWidth(2);
        canvas.drawCircle(x, y, radius / 3, this.paint);
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public int dip2px( float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    public List<OrderStatusDescribeInfo> mornal = new ArrayList<>();

    public void setMornal(List<OrderStatusDescribeInfo> mornal) {
        this.mornal = mornal;

        vivio = mornal.size();//控制显示多少个实心圆

        invalidate();
    }
}

实体类:

package org.yidont.ylife.send.bean;

/**
 * Created by li4236 on 16/7/28.
 * li4236@aliyun.com
 */
public class OrderStatusDescribeInfo {


    private String status;
    private String time;
    private String text;

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

布局使用:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"

              android:background="@color/yidont_gray"
              android:orientation="vertical">


    <org.yidont.ylife.send.view.CustomRoundTrue
        android:id="@+id/send_round"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@color/yidont_white"/>


</LinearLayout>

使用方法:

 CustomRoundTrue    mRoundTrue = (CustomRoundTrue) findViewById(R.id.send_round);

        List<OrderStatusDescribeInfo> mornal = new ArrayList<>();

        mRoundTrue.setMornal(mornal);

实际项目效果图
这里写图片描述

如果有问题,欢迎指正!Android开发小白

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值