android添加订单的方法,Android 开发订单流程view实例详解

Android 开发订单流程view实例详解

先看看最终效果图:

ecd7fb37a9f0440f6fafebb54ee14368.gif

怎么样,效果还是很不错的吧?群里有人说切四张图的、recycleview的、各种的都有啊,但是最简单的就是通过自定义view来实现了~接下来让我们来实现下这个(订单流程view)。

首先我们定义好我们的自定义属性:

attrs.xml

然后就是我们的老套路了,创建一个叫ProcessView的类继承view,然后定义好我们需要的属性:

/**

* Created by leo on 17/3/27.

*/

public class ProcessView extends View {

/**

* 默认线宽度

*/

private static final float D_LINE_WIDTH = 3;

/**

* 默认滑动圆点半径

*/

private static final float D_THUMB_RADIUS = 10;

/**

* 默认textsize

*/

private static final float D_TEXT_SIZE = 13f;

private static final int D_REACH_COLOR = 0xFFF1AE0D;

private static final int D_UNREACH_COLOR = Color.WHITE;

private static final int D_TEXT_COLOR = Color.WHITE;

private Paint linePaint;

private TextPaint textPaint;

private Paint thumbPaint;

private float mTextSize = xx2px(TypedValue.COMPLEX_UNIT_SP, D_TEXT_SIZE);

private float mLineWidth = xx2px(TypedValue.COMPLEX_UNIT_DIP, D_LINE_WIDTH);

private float mThumbRadius = xx2px(TypedValue.COMPLEX_UNIT_DIP, D_THUMB_RADIUS);

private int mReachedColor = D_REACH_COLOR;

private int mUnreachedColor = D_UNREACH_COLOR;

private int mTextColor = D_TEXT_COLOR;

//当前进度

private float mProgress = 0.0f;

//所有的状态文字

private String[] texts;

public ProcessView(Context context) {

this(context, null);

}

public ProcessView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public ProcessView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

obtainStyledAttrs(context, attrs, defStyleAttr);

initViews();

}

/**

* 获取我们的自定义属性

* @param context

* @param attrs

* @param defStyleAttr

*/

private void obtainStyledAttrs(Context context, AttributeSet attrs, int defStyleAttr) {

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

texts = a.hasValue(R.styleable.ProcessView_texts) ?

getResources().getStringArray(a.getResourceId(R.styleable.ProcessView_texts, 0)) : texts;

mLineWidth = a.hasValue(R.styleable.ProcessView_line_width) ?

a.getDimensionPixelSize(R.styleable.ProcessView_line_width, 0) : mLineWidth;

mThumbRadius = a.hasValue(R.styleable.ProcessView_thumb_radius) ?

a.getDimensionPixelSize(R.styleable.ProcessView_thumb_radius, 0) : mThumbRadius;

mTextSize = a.hasValue(R.styleable.ProcessView_textsize) ?

a.getDimensionPixelSize(R.styleable.ProcessView_text_color, 0) : mTextSize;

mReachedColor=a.hasValue(R.styleable.ProcessView_color_reached)?

a.getColor(R.styleable.ProcessView_color_reached,D_REACH_COLOR):D_REACH_COLOR;

mUnreachedColor=a.hasValue(R.styleable.ProcessView_color_unreached)?

a.getColor(R.styleable.ProcessView_color_unreached,D_UNREACH_COLOR):D_UNREACH_COLOR;

mTextColor=a.hasValue(R.styleable.ProcessView_text_color)?

a.getColor(R.styleable.ProcessView_text_color,D_TEXT_COLOR):D_TEXT_COLOR;

a.recycle();

}

/**

* 初始化一些对象

*/

private void initViews() {

linePaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);

linePaint.setStyle(Paint.Style.FILL);

textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);

thumbPaint = new Paint(linePaint);

textPaint.setTextSize(mTextSize);

textPaint.setColor(mTextColor);

linePaint.setStrokeWidth(mLineWidth);

}

然后就是重写我们的onmeasure方法了,我们这里就不考虑控件的高度为wrap_content这种情况了,所以我们只需要测量高度就可以了:

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int heightM = MeasureSpec.getMode(heightMeasureSpec);

int defaultW = MeasureSpec.getSize(widthMeasureSpec);

int defaultH = MeasureSpec.getSize(heightMeasureSpec);

int resultW, resultH;

resultW = defaultW;

resultH = getDefaultHeight(defaultH, heightM);

setMeasuredDimension(resultW, resultH);

}

private int getDefaultHeight(int height, int mode) {

int result;

if (mode == MeasureSpec.EXACTLY) {

result = height;

} else {

//获取文字的高度

float textH = (textPaint.getFontMetrics().bottom - textPaint.getFontMetrics().top);

//高度=圆半径+2.2*线条宽度(也就是竖线高度)+文字高度*1.3(也就是空隙高度)+0.5*文字高度

result = (int) (mThumbRadius + mLineWidth * 2.2f + textH * 1.3f + 0.5 * textH);

}

return result;

}

接着就是我们的核心方法onDraw()了,代码很简单都有注释,我就不一一解释了:

@Override

protected void onDraw(Canvas canvas) {

//画底部的竖线跟文字

drawFoot(canvas);

//画移动的小圆点跟进度条

drawProgressAndThumb(canvas);

}

/**

* 画底部的竖线跟文字

*/

private void drawFoot(Canvas canvas) {

//设置底部竖线宽度(底部的竖线会比进度条的要小一点)

float lineWidth = mLineWidth * 0.8f;

linePaint.setStrokeWidth(mLineWidth * 0.8f);

//起始位置(也就是"订单已提交"的"已"字位置)

float startX = textPaint.measureText(texts[0]) / 2;

//结束的文字的位置("已送达"的"送"字位置)

float endTextW = textPaint.measureText(texts[texts.length - 1]) / 2;

//绘制的终点位置

float endX = getMeasuredWidth() - endTextW;

//线条的总长度

float lineW = (endX - startX) / (texts.length - 1);

//竖线的高度

float lineH = mLineWidth * 2.2f;

//竖线的终点位置

float lineY = mThumbRadius + mLineWidth / 2;

//循环画出竖线跟文字

for (int i = 0; i < texts.length; i++) {

canvas.save();

//每画一条竖线让画布水平平移linew个宽度

canvas.translate(i * lineW, 0);

//如果当前进度>竖线所在的位置,就改变竖线的颜色

linePaint.setColor(i * lineW >= mProgress * (endX - startX) ? mUnreachedColor : mReachedColor);

float endX2 = i == texts.length - 1 ? startX - lineWidth / 2 : startX + lineWidth / 2;

canvas.drawLine(endX2, lineY, endX2, lineY + lineH, linePaint);

//画文字

textPaint.setTextAlign(Paint.Align.CENTER);

float textH = (textPaint.getFontMetrics().bottom - textPaint.getFontMetrics().top);

canvas.drawText(texts[i], endX2, lineY + lineH + textH * 1.3f, textPaint);

canvas.restore();

}

}

private void drawProgressAndThumb(Canvas canvas) {

float startX = textPaint.measureText(texts[0]) / 2;

float endTextW = textPaint.measureText(texts[texts.length - 1]) / 2;

float endX = getMeasuredWidth() - endTextW;

float lineY = mThumbRadius;

linePaint.setStrokeWidth(mLineWidth);

//draw basic line

linePaint.setColor(mUnreachedColor);

canvas.drawLine(startX, lineY, endX, lineY, linePaint);

//draw progress line

float progressX = startX + (endX - startX) * mProgress;

linePaint.setColor(mReachedColor);

canvas.drawLine(startX, lineY, progressX, lineY, linePaint);

//给移动圆点一个RadialGradient颜色梯度效果

thumbPaint.setShader(new RadialGradient(progressX, mThumbRadius, mThumbRadius, new int[]{Color.WHITE, D_REACH_COLOR, Color.YELLOW}, null, Shader.TileMode.REPEAT));

canvas.drawCircle(progressX, mThumbRadius, mThumbRadius, thumbPaint);

}

好啦~~然后我们暴露一个方法给外部,修改progress:

public void setProgress(float progress) {

if (progress != mProgress) {

mProgress = progress;

if (Looper.myLooper() == Looper.getMainLooper()) {

invalidate();

} else {

postInvalidate();

}

}

}

最后我们就可以跑起来了:

activity_main.xml

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

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

android:id="@+id/activity_main"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

android:paddingBottom="@dimen/activity_vertical_margin"

android:background="#b2000000"

android:orientation="vertical"

>

android:layout_width="match_parent"

android:layout_height="wrap_content"

app:cardCornerRadius="5dp"

app:cardElevation="3dp"

app:cardBackgroundColor="#FF2384DD"

>

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical"

android:padding="10dp"

>

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="商家已接单"

android:textSize="14.5sp"

android:textColor="#FFF1AE0D"

/>

android:layout_marginTop="5dp"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="订单超过12小时自动完成"

android:textSize="13sp"

android:textColor="#fff"

/>

android:layout_marginTop="10dp"

android:layout_marginBottom="10dp"

android:layout_width="match_parent"

android:layout_height="2dp"

android:background="@drawable/bg_line"

android:layerType="software"

/>

android:id="@+id/id_process"

android:layout_width="match_parent"

android:layout_height="wrap_content"

app:texts="@array/process_states"

/>

arrays.xml:

订单已提交

已付款

商家已接单

已送达

然后是我们的测试activity:

package com.yasin.processdemo;

import android.animation.ValueAnimator;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.view.animation.AccelerateDecelerateInterpolator;

import com.yasin.processdemo.view.ProcessView;

public class MainActivity extends AppCompatActivity {

private ProcessView mProcessView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mProcessView= (ProcessView) findViewById(R.id.id_process);

startAni();

}

private void startAni() {

ValueAnimator a = ValueAnimator.ofFloat(0, 1);

a.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

float progress = (float) animation.getAnimatedValue();

mProcessView.setProgress(progress);

}

});

a.setDuration(10000);

a.setInterpolator(new AccelerateDecelerateInterpolator());

a.start();

}

}

最后附上processview的全部代码:

package com.yasin.processdemo.view;

import android.content.Context;

import android.content.res.Resources;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.RadialGradient;

import android.graphics.Shader;

import android.os.Looper;

import android.text.TextPaint;

import android.util.AttributeSet;

import android.util.Log;

import android.util.TypedValue;

import android.view.View;

import com.yasin.processdemo.R;

/**

* Created by leo on 17/3/27.

*/

public class ProcessView extends View {

/**

* 默认线宽度

*/

private static final float D_LINE_WIDTH = 3;

/**

* 默认滑动圆点半径

*/

private static final float D_THUMB_RADIUS = 10;

/**

* 默认textsize

*/

private static final float D_TEXT_SIZE = 13f;

private static final int D_REACH_COLOR = 0xFFF1AE0D;

private static final int D_UNREACH_COLOR = Color.WHITE;

private static final int D_TEXT_COLOR = Color.WHITE;

private Paint linePaint;

private TextPaint textPaint;

private Paint thumbPaint;

private float mTextSize = xx2px(TypedValue.COMPLEX_UNIT_SP, D_TEXT_SIZE);

private float mLineWidth = xx2px(TypedValue.COMPLEX_UNIT_DIP, D_LINE_WIDTH);

private float mThumbRadius = xx2px(TypedValue.COMPLEX_UNIT_DIP, D_THUMB_RADIUS);

private int mReachedColor = D_REACH_COLOR;

private int mUnreachedColor = D_UNREACH_COLOR;

private int mTextColor = D_TEXT_COLOR;

//当前进度

private float mProgress = 0.0f;

//所有的状态文字

private String[] texts;

public ProcessView(Context context) {

this(context, null);

}

public ProcessView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public ProcessView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

obtainStyledAttrs(context, attrs, defStyleAttr);

initViews();

}

/**

* 获取我们的自定义属性

* @param context

* @param attrs

* @param defStyleAttr

*/

private void obtainStyledAttrs(Context context, AttributeSet attrs, int defStyleAttr) {

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

texts = a.hasValue(R.styleable.ProcessView_texts) ?

getResources().getStringArray(a.getResourceId(R.styleable.ProcessView_texts, 0)) : texts;

mLineWidth = a.hasValue(R.styleable.ProcessView_line_width) ?

a.getDimensionPixelSize(R.styleable.ProcessView_line_width, 0) : mLineWidth;

mThumbRadius = a.hasValue(R.styleable.ProcessView_thumb_radius) ?

a.getDimensionPixelSize(R.styleable.ProcessView_thumb_radius, 0) : mThumbRadius;

mTextSize = a.hasValue(R.styleable.ProcessView_textsize) ?

a.getDimensionPixelSize(R.styleable.ProcessView_text_color, 0) : mTextSize;

mReachedColor=a.hasValue(R.styleable.ProcessView_color_reached)?

a.getColor(R.styleable.ProcessView_color_reached,D_REACH_COLOR):D_REACH_COLOR;

mUnreachedColor=a.hasValue(R.styleable.ProcessView_color_unreached)?

a.getColor(R.styleable.ProcessView_color_unreached,D_UNREACH_COLOR):D_UNREACH_COLOR;

mTextColor=a.hasValue(R.styleable.ProcessView_text_color)?

a.getColor(R.styleable.ProcessView_text_color,D_TEXT_COLOR):D_TEXT_COLOR;

a.recycle();

}

/**

* 初始化一些对象

*/

private void initViews() {

linePaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);

linePaint.setStyle(Paint.Style.FILL);

textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);

thumbPaint = new Paint(linePaint);

textPaint.setTextSize(mTextSize);

textPaint.setColor(mTextColor);

linePaint.setStrokeWidth(mLineWidth);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int heightM = MeasureSpec.getMode(heightMeasureSpec);

int defaultW = MeasureSpec.getSize(widthMeasureSpec);

int defaultH = MeasureSpec.getSize(heightMeasureSpec);

int resultW, resultH;

resultW = defaultW;

resultH = getDefaultHeight(defaultH, heightM);

setMeasuredDimension(resultW, resultH);

}

private int getDefaultHeight(int height, int mode) {

int result;

if (mode == MeasureSpec.EXACTLY) {

result = height;

} else {

//获取文字的高度

float textH = (textPaint.getFontMetrics().bottom - textPaint.getFontMetrics().top);

//高度=圆半径+2.2*线条宽度(也就是竖线高度)+文字高度*1.3(也就是空隙高度)+0.5*文字高度

result = (int) (mThumbRadius + mLineWidth * 2.2f + textH * 1.3f + 0.5 * textH);

}

return result;

}

@Override

protected void onDraw(Canvas canvas) {

//画底部的竖线跟文字

drawFoot(canvas);

//画移动的小圆点跟进度条

drawProgressAndThumb(canvas);

}

/**

* 画底部的竖线跟文字

*/

private void drawFoot(Canvas canvas) {

//设置底部竖线宽度(底部的竖线会比进度条的要小一点)

float lineWidth = mLineWidth * 0.8f;

linePaint.setStrokeWidth(mLineWidth * 0.8f);

//起始位置(也就是"订单已提交"的"已"字位置)

float startX = textPaint.measureText(texts[0]) / 2;

//结束的文字的位置("已送达"的"送"字位置)

float endTextW = textPaint.measureText(texts[texts.length - 1]) / 2;

//绘制的终点位置

float endX = getMeasuredWidth() - endTextW;

//线条的总长度

float lineW = (endX - startX) / (texts.length - 1);

//竖线的高度

float lineH = mLineWidth * 2.2f;

//竖线的终点位置

float lineY = mThumbRadius + mLineWidth / 2;

//循环画出竖线跟文字

for (int i = 0; i < texts.length; i++) {

canvas.save();

//每画一条竖线让画布水平平移linew个宽度

canvas.translate(i * lineW, 0);

//如果当前进度>竖线所在的位置,就改变竖线的颜色

linePaint.setColor(i * lineW >= mProgress * (endX - startX) ? mUnreachedColor : mReachedColor);

float endX2 = i == texts.length - 1 ? startX - lineWidth / 2 : startX + lineWidth / 2;

canvas.drawLine(endX2, lineY, endX2, lineY + lineH, linePaint);

//画文字

textPaint.setTextAlign(Paint.Align.CENTER);

float textH = (textPaint.getFontMetrics().bottom - textPaint.getFontMetrics().top);

canvas.drawText(texts[i], endX2, lineY + lineH + textH * 1.3f, textPaint);

canvas.restore();

}

}

private void drawProgressAndThumb(Canvas canvas) {

float startX = textPaint.measureText(texts[0]) / 2;

float endTextW = textPaint.measureText(texts[texts.length - 1]) / 2;

float endX = getMeasuredWidth() - endTextW;

float lineY = mThumbRadius;

linePaint.setStrokeWidth(mLineWidth);

//draw basic line

linePaint.setColor(mUnreachedColor);

canvas.drawLine(startX, lineY, endX, lineY, linePaint);

//draw progress line

float progressX = startX + (endX - startX) * mProgress;

linePaint.setColor(mReachedColor);

canvas.drawLine(startX, lineY, progressX, lineY, linePaint);

//给移动圆点一个RadialGradient颜色梯度效果

thumbPaint.setShader(new RadialGradient(progressX, mThumbRadius, mThumbRadius, new int[]{Color.WHITE, D_REACH_COLOR, Color.YELLOW}, null, Shader.TileMode.REPEAT));

canvas.drawCircle(progressX, mThumbRadius, mThumbRadius, thumbPaint);

}

public void setProgress(float progress) {

if (progress != mProgress) {

mProgress = progress;

if (Looper.myLooper() == Looper.getMainLooper()) {

invalidate();

} else {

postInvalidate();

}

}

}

private float xx2px(int unit, float value) {

Context c = getContext();

Resources r;

if (c == null)

r = Resources.getSystem();

else

r = c.getResources();

return (TypedValue.applyDimension(

unit, value, r.getDisplayMetrics()));

}

}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值