parent
3f35a227f0
commit
d6000bd5ce
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,209 @@
|
|||||||
|
package com.sbw.atrue.Order.Activity;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
|
import com.sbw.atrue.Order.R;
|
||||||
|
|
||||||
|
//import practice.csy.com.customprogress.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by user on 2017-8-8.
|
||||||
|
* <p>
|
||||||
|
* 直接继承ProgressBar可以实现进度额保存
|
||||||
|
* <p>
|
||||||
|
* 不带数字进度
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CustomHorizontalProgresNoNum extends ProgressBar {
|
||||||
|
|
||||||
|
//默认值
|
||||||
|
private static final int DEAFUALT_PROGRESS_UNREACH_HEIGHH = 10;//dp
|
||||||
|
protected static final int DEAFUALT_PROGRESS_UNREACH_CORLOR = 0xFFD3D6DA;
|
||||||
|
private static final int DEAFUALT_PROGRESS_REACH_HEIGHH = 10;//dp
|
||||||
|
protected static final int DEAFUALT_PROGRESS_REACH_CORLOR = 0xFFFC00D1;
|
||||||
|
protected static final int DEAFUALT_PROGRESS_TEXT_SIZE = 10;//sp
|
||||||
|
protected static final int DEAFUALT_PROGRESS_TEXT_CORLOR = 0xFFD3D6DA;
|
||||||
|
protected static final int DEAFUALT_PROGRESS_TEXT_OFFSET = 10;//dp
|
||||||
|
private static final int DEAFUALT_PROGRESS_VIEW_WIDTH = 200;//进度条默认宽度
|
||||||
|
|
||||||
|
protected int HorizontalProgresUnReachColor;//不能用static修饰,不然多个View会共用此属性
|
||||||
|
private int HorizontalProgresUnReachHeight;
|
||||||
|
protected int HorizontalProgresReachColor;
|
||||||
|
private int HorizontalProgresReachHeight;
|
||||||
|
protected int HorizontalProgresTextColor;
|
||||||
|
protected int HorizontalProgresTextSize;
|
||||||
|
protected int HorizontalProgresTextOffset;
|
||||||
|
|
||||||
|
protected Paint mPaint = new Paint();
|
||||||
|
//protected float[] rids = {15.0f, 15.0f, 15.0f, 15.0f, 0.0f, 0.0f, 0.0f, 0.0f,}; 上面圆角
|
||||||
|
|
||||||
|
protected Path path;
|
||||||
|
protected float[] rids = {15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f,};//四个角都圆角
|
||||||
|
public CustomHorizontalProgresNoNum(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomHorizontalProgresNoNum(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomHorizontalProgresNoNum(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
getStyleabletAttr(attrs);
|
||||||
|
mPaint.setTextSize(HorizontalProgresTextSize);//设置画笔文字大小,便于后面测量文字宽高
|
||||||
|
mPaint.setColor(HorizontalProgresTextColor);
|
||||||
|
path = new Path();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自定义属性
|
||||||
|
*/
|
||||||
|
protected void getStyleabletAttr(AttributeSet attrs) {
|
||||||
|
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CustomHorizontalProgresStyle);
|
||||||
|
HorizontalProgresUnReachColor = typedArray.getColor(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresUnReachColor, DEAFUALT_PROGRESS_UNREACH_CORLOR);
|
||||||
|
HorizontalProgresReachColor = typedArray.getColor(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresReachColor, DEAFUALT_PROGRESS_REACH_CORLOR);
|
||||||
|
//将sp、dp统一转换为sp
|
||||||
|
HorizontalProgresReachHeight = (int) typedArray.getDimension(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresReachHeight, dp2px(getContext(), DEAFUALT_PROGRESS_REACH_HEIGHH));
|
||||||
|
HorizontalProgresUnReachHeight = (int) typedArray.getDimension(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresUnReachHeight, dp2px(getContext(), DEAFUALT_PROGRESS_UNREACH_HEIGHH));
|
||||||
|
HorizontalProgresTextColor = typedArray.getColor(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresTextColor, DEAFUALT_PROGRESS_TEXT_CORLOR);
|
||||||
|
HorizontalProgresTextSize = (int) typedArray.getDimension(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresTextSize, sp2px(getContext(), DEAFUALT_PROGRESS_TEXT_SIZE));
|
||||||
|
HorizontalProgresTextOffset = (int) typedArray.getDimension(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresTextOffset, DEAFUALT_PROGRESS_TEXT_OFFSET);
|
||||||
|
typedArray.recycle();//记得加这句
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
int width = measureWidth(widthMeasureSpec);//计算宽高
|
||||||
|
int height = measureHeight(heightMeasureSpec);
|
||||||
|
setMeasuredDimension(width, height);//设置宽高
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected synchronized void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
|
||||||
|
canvas.save();//save、restore 图层的保存和回滚相关的方法 详见 http://blog.csdn.net/tianjian4592/article/details/45234419
|
||||||
|
canvas.translate(0, getHeight() / 2);//移动图层到垂直居中位置
|
||||||
|
|
||||||
|
|
||||||
|
float radio = getProgress() * 1.0f / getMax();
|
||||||
|
float realWidth = getWidth() - getPaddingLeft() - getPaddingRight();//实际宽度减去文字宽度
|
||||||
|
float progressX = radio * realWidth;
|
||||||
|
|
||||||
|
/*向路径中添加圆角矩形。radii数组定义圆角矩形的四个圆角的x,y半径。radii长度必须为8*/
|
||||||
|
path.addRoundRect(new RectF(getPaddingLeft(),getPaddingTop()-HorizontalProgresReachHeight/2,realWidth,HorizontalProgresReachHeight/2), rids, Path.Direction.CW);
|
||||||
|
canvas.clipPath(path);
|
||||||
|
|
||||||
|
//绘制走完的进度线
|
||||||
|
mPaint.setColor(HorizontalProgresReachColor);
|
||||||
|
mPaint.setStrokeWidth(HorizontalProgresReachHeight);
|
||||||
|
//canvas.drawLine(getPaddingLeft(), getPaddingTop(), progressX, getPaddingTop(), mPaint);//直角 垂直在同一高度 float startY, float stopY 一样
|
||||||
|
RectF mRectF = new RectF(getPaddingLeft(),getPaddingTop()-HorizontalProgresReachHeight/2,(int)progressX,HorizontalProgresReachHeight/2);//圆角 int left, int top, int right, int bottom
|
||||||
|
canvas.drawRoundRect(mRectF,0,0,mPaint);//圆角矩形
|
||||||
|
|
||||||
|
//绘制未做走完的进度
|
||||||
|
if (progressX < getWidth() - getPaddingLeft() - getPaddingRight()) {//进度走完了,不再画未走完的
|
||||||
|
mPaint.setColor(HorizontalProgresUnReachColor);
|
||||||
|
mPaint.setStrokeWidth(HorizontalProgresUnReachHeight);
|
||||||
|
//canvas.drawLine(progressX, getPaddingTop(), getWidth() - getPaddingLeft() - getPaddingRight(), getPaddingTop(), mPaint);//垂直在同一高度 float startY, float stopY 一样
|
||||||
|
RectF mRectF2 = new RectF(progressX - 15 ,getPaddingTop()-HorizontalProgresUnReachHeight/2,realWidth,HorizontalProgresUnReachHeight/2);//圆角 int left, int top, int right, int bottom
|
||||||
|
canvas.drawRoundRect(mRectF2,0,0,mPaint);//圆角矩形
|
||||||
|
}
|
||||||
|
canvas.restore();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp转px
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param dpVal
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int dp2px(Context context, float dpVal) {
|
||||||
|
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
|
||||||
|
dpVal, context.getResources().getDisplayMetrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sp转px
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param spVal
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int sp2px(Context context, float spVal) {
|
||||||
|
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
spVal, context.getResources().getDisplayMetrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the width of this view
|
||||||
|
*
|
||||||
|
* @param measureSpec A measureSpec packed into an int
|
||||||
|
* @return The width of the view, honoring constraints from measureSpec
|
||||||
|
*/
|
||||||
|
protected int measureWidth(int measureSpec) {
|
||||||
|
int result = 0;
|
||||||
|
int specMode = MeasureSpec.getMode(measureSpec);
|
||||||
|
int specSize = MeasureSpec.getSize(measureSpec);
|
||||||
|
|
||||||
|
if (specMode == MeasureSpec.EXACTLY) {
|
||||||
|
// We were told how big to be
|
||||||
|
result = specSize;
|
||||||
|
} else {
|
||||||
|
// Measure the text
|
||||||
|
result = dp2px(getContext(), DEAFUALT_PROGRESS_VIEW_WIDTH);//
|
||||||
|
if (specMode == MeasureSpec.AT_MOST) {
|
||||||
|
// Respect AT_MOST value if that was what is called for by measureSpec
|
||||||
|
result = Math.min(result, specSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the height of this view
|
||||||
|
*
|
||||||
|
* @param measureSpec A measureSpec packed into an int
|
||||||
|
* @return The height of the view, honoring constraints from measureSpec
|
||||||
|
*/
|
||||||
|
protected int measureHeight(int measureSpec) {
|
||||||
|
int result = 0;
|
||||||
|
int specMode = MeasureSpec.getMode(measureSpec);
|
||||||
|
int specSize = MeasureSpec.getSize(measureSpec);
|
||||||
|
|
||||||
|
if (specMode == MeasureSpec.EXACTLY) {
|
||||||
|
// We were told how big to be
|
||||||
|
result = specSize;
|
||||||
|
} else {
|
||||||
|
// Measure the text (beware: ascent is a negative number)
|
||||||
|
//此处高度为走完的进度高度和未走完的机大以及文字的高度的最大值
|
||||||
|
int textHeight = (int) (mPaint.descent() - mPaint.ascent());//得到字的高度有二种方式,第一种是React,第二种这个
|
||||||
|
result = Math.max(textHeight, Math.max(HorizontalProgresReachHeight, HorizontalProgresUnReachHeight)) + getPaddingTop()
|
||||||
|
+ getPaddingBottom();
|
||||||
|
if (specMode == MeasureSpec.AT_MOST) {
|
||||||
|
// Respect AT_MOST value if that was what is called for by measureSpec
|
||||||
|
result = Math.min(result, specSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,200 @@
|
|||||||
|
package com.sbw.atrue.Order.Activity;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
|
import com.sbw.atrue.Order.R;
|
||||||
|
|
||||||
|
//import practice.csy.com.customprogress.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by user on 2017-8-8.
|
||||||
|
*
|
||||||
|
* 直接继承ProgressBar可以实现进度额保存
|
||||||
|
*
|
||||||
|
* 带数字进度
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CustomHorizontalProgresWithNum extends ProgressBar{
|
||||||
|
|
||||||
|
//默认值
|
||||||
|
private static final int DEAFUALT_PROGRESS_UNREACH_HEIGHH = 10;//dp
|
||||||
|
protected static final int DEAFUALT_PROGRESS_UNREACH_CORLOR = 0xFFD3D6DA;
|
||||||
|
protected static final int DEAFUALT_PROGRESS_REACH_HEIGHH = 10;//dp
|
||||||
|
protected static final int DEAFUALT_PROGRESS_REACH_CORLOR = 0xFFFC00D1;
|
||||||
|
protected static final int DEAFUALT_PROGRESS_TEXT_SIZE = 10;//sp
|
||||||
|
protected static final int DEAFUALT_PROGRESS_TEXT_CORLOR = 0xFFD3D6DA;
|
||||||
|
protected static final int DEAFUALT_PROGRESS_TEXT_OFFSET = 10;//dp
|
||||||
|
protected static final int DEAFUALT_PROGRESS_VIEW_WIDTH = 200;//进度条默认宽度
|
||||||
|
|
||||||
|
protected int HorizontalProgresUnReachColor;//不能用static修饰,不然多个View会共用此属性
|
||||||
|
private int HorizontalProgresUnReachHeight;
|
||||||
|
protected int HorizontalProgresReachColor;
|
||||||
|
private int HorizontalProgresReachHeight;
|
||||||
|
protected int HorizontalProgresTextColor;
|
||||||
|
protected int HorizontalProgresTextSize;
|
||||||
|
protected int HorizontalProgresTextOffset;
|
||||||
|
|
||||||
|
protected Paint mPaint = new Paint();
|
||||||
|
public CustomHorizontalProgresWithNum(Context context) {
|
||||||
|
this(context,null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomHorizontalProgresWithNum(Context context, AttributeSet attrs) {
|
||||||
|
this(context,attrs,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomHorizontalProgresWithNum(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
getStyleabletAttr(attrs);
|
||||||
|
mPaint.setTextSize(HorizontalProgresTextSize);//设置画笔文字大小,便于后面测量文字宽高
|
||||||
|
mPaint.setColor(HorizontalProgresTextColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自定义属性
|
||||||
|
*/
|
||||||
|
protected void getStyleabletAttr(AttributeSet attrs) {
|
||||||
|
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CustomHorizontalProgresStyle);
|
||||||
|
HorizontalProgresUnReachColor = typedArray.getColor(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresUnReachColor,DEAFUALT_PROGRESS_UNREACH_CORLOR);
|
||||||
|
HorizontalProgresReachColor = typedArray.getColor(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresReachColor,DEAFUALT_PROGRESS_REACH_CORLOR);
|
||||||
|
//将sp、dp统一转换为sp
|
||||||
|
HorizontalProgresReachHeight = (int) typedArray.getDimension(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresReachHeight,dp2px(getContext(),DEAFUALT_PROGRESS_REACH_HEIGHH));
|
||||||
|
HorizontalProgresUnReachHeight = (int) typedArray.getDimension(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresUnReachHeight,dp2px(getContext(),DEAFUALT_PROGRESS_UNREACH_HEIGHH));
|
||||||
|
HorizontalProgresTextColor = typedArray.getColor(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresTextColor,DEAFUALT_PROGRESS_TEXT_CORLOR);
|
||||||
|
HorizontalProgresTextSize = (int) typedArray.getDimension(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresTextSize,sp2px(getContext(),DEAFUALT_PROGRESS_TEXT_SIZE));
|
||||||
|
HorizontalProgresTextOffset = (int) typedArray.getDimension(R.styleable.CustomHorizontalProgresStyle_HorizontalProgresTextOffset,DEAFUALT_PROGRESS_TEXT_OFFSET);
|
||||||
|
typedArray.recycle();//记得加这句
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
int width = measureWidth(widthMeasureSpec);//计算宽高
|
||||||
|
int height = measureHeight(heightMeasureSpec);
|
||||||
|
setMeasuredDimension(width,height);//设置宽高
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected synchronized void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
|
||||||
|
canvas.save();//save、restore 图层的保存和回滚相关的方法 详见 http://blog.csdn.net/tianjian4592/article/details/45234419
|
||||||
|
canvas.translate(0,getHeight()/2);//移动图层到垂直居中位置
|
||||||
|
float radio = getProgress()*1.0f/getMax();
|
||||||
|
int textWidth = (int) mPaint.measureText(getProgress()+"%");//The width of the text
|
||||||
|
float realWidth = getWidth() - getPaddingLeft() - getPaddingRight() - textWidth - HorizontalProgresTextOffset;//实际宽度减去文字宽度
|
||||||
|
float progressX = radio * realWidth ;
|
||||||
|
//绘制走完的进度线
|
||||||
|
mPaint.setColor(HorizontalProgresReachColor);
|
||||||
|
mPaint.setStrokeWidth(HorizontalProgresReachHeight);
|
||||||
|
//canvas.drawLine(getPaddingLeft(),getPaddingTop(),progressX,getPaddingTop(),mPaint);//直角 垂直在同一高度 float startY, float stopY 一样
|
||||||
|
RectF mRectF = new RectF(getPaddingLeft(),getPaddingTop()-HorizontalProgresReachHeight/2,(int)progressX,HorizontalProgresReachHeight/2);//圆角 int left, int top, int right, int bottom
|
||||||
|
canvas.drawRoundRect(mRectF,15,15,mPaint);//圆角矩形
|
||||||
|
//绘制进度
|
||||||
|
mPaint.setColor(HorizontalProgresTextColor);
|
||||||
|
mPaint.setTextSize(HorizontalProgresTextSize);
|
||||||
|
int y = (int) -((mPaint.descent() + mPaint.ascent())/2);//文字居中
|
||||||
|
canvas.drawText(getProgress()+"%",progressX + HorizontalProgresTextOffset/2,getPaddingTop() + y,mPaint);
|
||||||
|
//绘制未做走完的进度
|
||||||
|
if (progressX + HorizontalProgresTextOffset + textWidth < getWidth() - getPaddingLeft() - getPaddingRight()){//进度走完了,不再画未走完的
|
||||||
|
mPaint.setColor(HorizontalProgresUnReachColor);
|
||||||
|
mPaint.setStrokeWidth(HorizontalProgresUnReachHeight);
|
||||||
|
//canvas.drawLine(getPaddingLeft()+progressX + HorizontalProgresTextOffset + textWidth,getPaddingTop(),getWidth() - getPaddingLeft() - getPaddingRight() ,getPaddingTop(),mPaint);//垂直在同一高度 float startY, float stopY 一样
|
||||||
|
RectF mRectF2 = new RectF(progressX + HorizontalProgresTextOffset + textWidth,getPaddingTop()-HorizontalProgresUnReachHeight/2,realWidth,HorizontalProgresUnReachHeight/2);//圆角 int left, int top, int right, int bottom
|
||||||
|
canvas.drawRoundRect(mRectF2,15,15,mPaint);//圆角矩形
|
||||||
|
}
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp转px
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param dpVal
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int dp2px(Context context, float dpVal)
|
||||||
|
{
|
||||||
|
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
|
||||||
|
dpVal, context.getResources().getDisplayMetrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sp转px
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param spVal
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int sp2px(Context context, float spVal)
|
||||||
|
{
|
||||||
|
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
spVal, context.getResources().getDisplayMetrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the width of this view
|
||||||
|
* @param measureSpec A measureSpec packed into an int
|
||||||
|
* @return The width of the view, honoring constraints from measureSpec
|
||||||
|
*/
|
||||||
|
protected int measureWidth(int measureSpec) {
|
||||||
|
int result = 0;
|
||||||
|
int specMode = MeasureSpec.getMode(measureSpec);
|
||||||
|
int specSize = MeasureSpec.getSize(measureSpec);
|
||||||
|
|
||||||
|
if (specMode == MeasureSpec.EXACTLY) {
|
||||||
|
// We were told how big to be
|
||||||
|
result = specSize;
|
||||||
|
} else {
|
||||||
|
// Measure the text
|
||||||
|
result = dp2px(getContext(),DEAFUALT_PROGRESS_VIEW_WIDTH);//
|
||||||
|
if (specMode == MeasureSpec.AT_MOST) {
|
||||||
|
// Respect AT_MOST value if that was what is called for by measureSpec
|
||||||
|
result = Math.min(result, specSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the height of this view
|
||||||
|
* @param measureSpec A measureSpec packed into an int
|
||||||
|
* @return The height of the view, honoring constraints from measureSpec
|
||||||
|
*/
|
||||||
|
protected int measureHeight(int measureSpec) {
|
||||||
|
int result = 0;
|
||||||
|
int specMode = MeasureSpec.getMode(measureSpec);
|
||||||
|
int specSize = MeasureSpec.getSize(measureSpec);
|
||||||
|
|
||||||
|
if (specMode == MeasureSpec.EXACTLY) {
|
||||||
|
// We were told how big to be
|
||||||
|
result = specSize;
|
||||||
|
} else {
|
||||||
|
// Measure the text (beware: ascent is a negative number)
|
||||||
|
//此处高度为走完的进度高度和未走完的机大以及文字的高度的最大值
|
||||||
|
int textHeight = (int) (mPaint.descent() - mPaint.ascent());//得到字的高度有二种方式,第一种是React,第二种这个
|
||||||
|
result = Math.max(textHeight,Math.max(HorizontalProgresReachHeight,HorizontalProgresUnReachHeight)) + getPaddingTop()
|
||||||
|
+ getPaddingBottom();
|
||||||
|
if (specMode == MeasureSpec.AT_MOST) {
|
||||||
|
// Respect AT_MOST value if that was what is called for by measureSpec
|
||||||
|
result = Math.min(result, specSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,37 @@
|
|||||||
package com.sbw.atrue.Order.Activity;
|
package com.sbw.atrue.Order.Activity;
|
||||||
|
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.sbw.atrue.Order.Entity.Product;
|
||||||
|
import com.sbw.atrue.Order.R;
|
||||||
|
import com.sbw.atrue.Order.Util.ProductListAdapter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
//健康结算界面
|
//健康结算界面
|
||||||
public class NutritionActivity {
|
public class NutritionActivity {
|
||||||
|
public static NutritionActivity mInstance = null; //当前对象的实例本身
|
||||||
|
|
||||||
|
private ListView lvNutrition; //商品展示列表控件
|
||||||
|
private TextView tvSelected; //已选择商品数量提示文字
|
||||||
|
private TextView tvTotal; //已选择商品总价提示文字
|
||||||
|
private Button btnTakeOrder; //下单按钮
|
||||||
|
private Button btnSortByNew; //根据新品排序
|
||||||
|
private Button btnSortBySale; //根据销量排序
|
||||||
|
private Button btnSortByPrice; //根据价格排序
|
||||||
|
private Button btnSortByAll; //根据综合情况排序
|
||||||
|
private List<Product> productsData = new ArrayList<Product>(); //所有的商品数据
|
||||||
|
private ArrayList<Product> selectedProducts = new ArrayList<Product>(); //被选择的的商品数据
|
||||||
|
private ProductListAdapter productListAdapter; //商品列表适配器
|
||||||
|
|
||||||
|
// private void initViews() {
|
||||||
|
// etname = (EditText) findViewById(R.id.et_name);
|
||||||
|
// etPhone = (EditText) findViewById(R.id.et_phone);
|
||||||
|
// ettable = (EditText) findViewById(R.id.et_table);
|
||||||
|
// btnInputCompleted = (Button) findViewById(R.id.btn_input_completed);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.sbw.atrue.Order.Activity;
|
||||||
|
|
||||||
|
//import android.support.v7.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import com.sbw.atrue.Order.Activity.CustomHorizontalProgresNoNum;
|
||||||
|
import com.sbw.atrue.Order.Activity.CustomHorizontalProgresWithNum;
|
||||||
|
import com.sbw.atrue.Order.R;
|
||||||
|
|
||||||
|
public class horizonta_main extends AppCompatActivity {
|
||||||
|
private CustomHorizontalProgresNoNum horizontalProgress01;//水平不带进度
|
||||||
|
private CustomHorizontalProgresWithNum horizontalProgress1,horizontalProgress2,horizontalProgress3;//水平带进度
|
||||||
|
private Timer timer,timer2,timer3;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
// setContentView(R.layout.activity_main);
|
||||||
|
setContentView(R.layout.horizontalprogres);
|
||||||
|
horizontalProgress01 = (CustomHorizontalProgresNoNum) findViewById(R.id.horizontalProgress01);
|
||||||
|
|
||||||
|
|
||||||
|
horizontalProgress1 = (CustomHorizontalProgresWithNum) findViewById(R.id.horizontalProgress1);
|
||||||
|
horizontalProgress2 = (CustomHorizontalProgresWithNum) findViewById(R.id.horizontalProgress2);
|
||||||
|
horizontalProgress3 = (CustomHorizontalProgresWithNum) findViewById(R.id.horizontalProgress3);
|
||||||
|
|
||||||
|
horizontalProgress1.setProgress(0);
|
||||||
|
horizontalProgress1.setMax(100);
|
||||||
|
|
||||||
|
horizontalProgress2.setProgress(0);
|
||||||
|
horizontalProgress2.setMax(100);
|
||||||
|
|
||||||
|
horizontalProgress3.setProgress(0);
|
||||||
|
horizontalProgress3.setMax(200);
|
||||||
|
|
||||||
|
|
||||||
|
timer = new Timer();
|
||||||
|
timer.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
//实时更新进度
|
||||||
|
if (horizontalProgress1.getProgress() >= 100) {//指定时间取消
|
||||||
|
timer.cancel();
|
||||||
|
}
|
||||||
|
horizontalProgress1.setProgress(horizontalProgress1.getProgress()+1);
|
||||||
|
horizontalProgress01.setProgress(horizontalProgress01.getProgress()+1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}, 50, 50);
|
||||||
|
|
||||||
|
timer2 = new Timer();
|
||||||
|
timer2.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
//实时更新进度
|
||||||
|
if (horizontalProgress2.getProgress() >= 100) {//指定时间取消
|
||||||
|
timer2.cancel();
|
||||||
|
}
|
||||||
|
horizontalProgress2.setProgress(horizontalProgress2.getProgress()+1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}, 40, 40);
|
||||||
|
|
||||||
|
|
||||||
|
timer3 = new Timer();
|
||||||
|
timer3.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
//实时更新进度
|
||||||
|
if (horizontalProgress3.getProgress() >= horizontalProgress3.getMax()) {//指定时间取消
|
||||||
|
timer3.cancel();
|
||||||
|
}
|
||||||
|
horizontalProgress3.setProgress(horizontalProgress3.getProgress()+1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}, 50, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
After Width: | Height: | Size: 57 KiB |
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<solid android:color="#82b2ff" />
|
<solid android:color="#BBAE99" />
|
||||||
<corners android:radius="25dp" />
|
<corners android:radius="25dp" />
|
||||||
</shape>
|
</shape>
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 549 KiB |
After Width: | Height: | Size: 992 KiB |
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
||||||
|
<solid android:color="#cc00cc"/>
|
||||||
|
</shape>
|
@ -0,0 +1,98 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
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"
|
||||||
|
android:background="#ffffff"
|
||||||
|
tools:context="com.sbw.atrue.Order.Activity.horizonta_main">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:text="蛋白质"
|
||||||
|
android:textColor="#36513e"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
></TextView>
|
||||||
|
<com.sbw.atrue.Order.Activity.CustomHorizontalProgresNoNum
|
||||||
|
android:layout_marginTop="0dp"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:id="@+id/horizontalProgress01"
|
||||||
|
android:progress="0"
|
||||||
|
app:HorizontalProgresReachColor="#00ffaa"
|
||||||
|
app:HorizontalProgresUnReachColor="#cab0b0"
|
||||||
|
app:HorizontalProgresTextColor="#00ffaa"
|
||||||
|
android:layout_width="300dp"
|
||||||
|
android:layout_height="50dp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:text="糖分"
|
||||||
|
android:textColor="#36513e"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
></TextView>
|
||||||
|
<com.sbw.atrue.Order.Activity.CustomHorizontalProgresWithNum
|
||||||
|
android:layout_marginTop="0dp"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:id="@+id/horizontalProgress1"
|
||||||
|
android:progress="0"
|
||||||
|
app:HorizontalProgresReachColor="#00ffaa"
|
||||||
|
app:HorizontalProgresUnReachColor="#cab0b0"
|
||||||
|
app:HorizontalProgresTextColor="#00ffaa"
|
||||||
|
android:layout_width="300dp"
|
||||||
|
android:layout_height="30dp">
|
||||||
|
</com.sbw.atrue.Order.Activity.CustomHorizontalProgresWithNum>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:text="维生素"
|
||||||
|
android:textColor="#36513e"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
></TextView>
|
||||||
|
<com.sbw.atrue.Order.Activity.CustomHorizontalProgresWithNum
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:id="@+id/horizontalProgress2"
|
||||||
|
android:progress="0"
|
||||||
|
android:background="#ffffff"
|
||||||
|
app:HorizontalProgresReachColor="#00ffaa"
|
||||||
|
app:HorizontalProgresUnReachColor="#cab0b0"
|
||||||
|
app:HorizontalProgresTextColor="#00ffaa"
|
||||||
|
android:layout_width="300dp"
|
||||||
|
android:layout_height="30dp">
|
||||||
|
|
||||||
|
</com.sbw.atrue.Order.Activity.CustomHorizontalProgresWithNum>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:text="其他"
|
||||||
|
android:textColor="#36513e"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
></TextView>
|
||||||
|
<com.sbw.atrue.Order.Activity.CustomHorizontalProgresWithNum
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:id="@+id/horizontalProgress3"
|
||||||
|
android:progress="0"
|
||||||
|
app:HorizontalProgresReachColor="#00ffaa"
|
||||||
|
app:HorizontalProgresUnReachColor="#cab0b0"
|
||||||
|
app:HorizontalProgresUnReachHeight="10dp"
|
||||||
|
app:HorizontalProgresReachHeight="10dp"
|
||||||
|
app:HorizontalProgresTextColor="#00FEA9"
|
||||||
|
android:layout_width="300dp"
|
||||||
|
android:layout_height="30dp">
|
||||||
|
</com.sbw.atrue.Order.Activity.CustomHorizontalProgresWithNum>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<attr name="ProgresUnReachColor" format="color"></attr>
|
||||||
|
<attr name="HorizontalProgresUnReachHeight" format="dimension"></attr>
|
||||||
|
<attr name="HorizontalProgresReachColor" format="color"></attr>
|
||||||
|
<attr name="HorizontalProgresUnReachColor" format="color"></attr>
|
||||||
|
|
||||||
|
<attr name="HorizontalProgresReachHeight" format="dimension"></attr>
|
||||||
|
<attr name="HorizontalProgresTextColor" format="color"></attr>
|
||||||
|
<attr name="HorizontalProgresTextSize" format="dimension"></attr>
|
||||||
|
<attr name="HorizontalProgresTextOffset" format="dimension"></attr>
|
||||||
|
<declare-styleable name="AnimatedCircleLoadingView">
|
||||||
|
<attr name="animCircleLoadingView_mainColor" format="color" localization="suggested" />
|
||||||
|
<attr name="animCircleLoadingView_secondaryColor" format="color" localization="suggested" />
|
||||||
|
<attr name="animCircleLoadingView_checkMarkTintColor" format="color" localization="suggested" />
|
||||||
|
<attr name="animCircleLoadingView_failureMarkTintColor" format="color" localization="suggested" />
|
||||||
|
<attr name="animCircleLoadingView_textColor" format="color" localization="suggested" />
|
||||||
|
</declare-styleable>
|
||||||
|
<declare-styleable name="CustomHorizontalProgresStyle">
|
||||||
|
<attr name="HorizontalProgresUnReachColor" ></attr>
|
||||||
|
<attr name="HorizontalProgresUnReachHeight" ></attr>
|
||||||
|
<attr name="HorizontalProgresReachColor" ></attr>
|
||||||
|
<attr name="HorizontalProgresReachHeight" ></attr>
|
||||||
|
<attr name="HorizontalProgresTextColor" ></attr>
|
||||||
|
<attr name="HorizontalProgresTextSize" ></attr>
|
||||||
|
<attr name="HorizontalProgresTextOffset"></attr>
|
||||||
|
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
|
|
||||||
|
<declare-styleable name="CustomCircleProgresStyle">
|
||||||
|
<attr name="CustomCircleRadio" format="dimension"></attr>
|
||||||
|
<attr name="CustomReachPaintStroken" format="dimension"></attr>
|
||||||
|
<attr name="CustomUnReachPaintStroken" format="dimension"></attr>
|
||||||
|
<attr name="CustomUnReachEnd" format="integer"></attr>
|
||||||
|
<attr name="CustomUnReachStart" format="integer"></attr>
|
||||||
|
<attr name="CustomHasProgressNum" format="boolean"></attr>
|
||||||
|
|
||||||
|
</declare-styleable>
|
||||||
|
</resources>
|
@ -1,3 +1,4 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">潮汕牛肉</string>
|
<string name="app_name">航吃Hang吃</string>
|
||||||
|
<string name="随即转盘">吃货大赏</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/caches/build_file_checksums.ser
|
||||||
|
/.idea/libraries
|
||||||
|
/.idea/modules.xml
|
||||||
|
/.idea/workspace.xml
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="WizardSettings">
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="vectorWizard">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="vectorAssetStep">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="clipartAsset">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="values">
|
||||||
|
<map>
|
||||||
|
<entry key="url" value="jar:file:/D:/Program%20Files%20(x86)/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/communication/ic_message_black_24dp.xml" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
<option name="values">
|
||||||
|
<map>
|
||||||
|
<entry key="outputName" value="ic_message_black_24dp" />
|
||||||
|
<entry key="sourceFile" value="C:\Users\ACER" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
Binary file not shown.
@ -0,0 +1,116 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<codeStyleSettings language="XML">
|
||||||
|
<indentOptions>
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
</indentOptions>
|
||||||
|
<arrangement>
|
||||||
|
<rules>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>xmlns:android</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>xmlns:.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:id</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*:name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>style</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<rule>
|
||||||
|
<match>
|
||||||
|
<AND>
|
||||||
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
|
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||||
|
</AND>
|
||||||
|
</match>
|
||||||
|
<order>BY_NAME</order>
|
||||||
|
</rule>
|
||||||
|
</section>
|
||||||
|
</rules>
|
||||||
|
</arrangement>
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<compositeConfiguration>
|
||||||
|
<compositeBuild compositeDefinitionSource="SCRIPT" />
|
||||||
|
</compositeConfiguration>
|
||||||
|
<option name="delegatedBuild" value="false" />
|
||||||
|
<option name="testRunner" value="GRADLE" />
|
||||||
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="JDK" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectType">
|
||||||
|
<option name="id" value="Android" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1 @@
|
|||||||
|
/build
|
@ -0,0 +1,38 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 28
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "com.sbw.atrue.Order"
|
||||||
|
minSdkVersion 16
|
||||||
|
targetSdkVersion 28
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
|
implementation 'androidx.appcompat:appcompat:1.2.0-beta01'
|
||||||
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
androidTestImplementation 'androidx.test:runner:1.3.0-beta01'
|
||||||
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0-beta01'
|
||||||
|
implementation 'com.google.android.material:material:1.2.0-alpha06'
|
||||||
|
implementation 'de.hdodenhof:circleimageview:2.1.0'
|
||||||
|
implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha03'
|
||||||
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
|
||||||
|
implementation 'androidx.cardview:cardview:1.0.0'
|
||||||
|
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
||||||
|
implementation 'org.litepal.android:core:1.3.2'
|
||||||
|
implementation 'com.yanzhenjie.nohttp:nohttp:1.1.4'
|
||||||
|
implementation 'com.google.code.gson:gson:2.8.6'
|
||||||
|
implementation files('libs/mysql-connector-java-5.1.38.jar')
|
||||||
|
}
|
Binary file not shown.
@ -0,0 +1,21 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.sbw.atrue.Order;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import androidx.test.InstrumentationRegistry;
|
||||||
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented test, which will execute on an Android device.
|
||||||
|
*
|
||||||
|
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ExampleInstrumentedTest {
|
||||||
|
@Test
|
||||||
|
public void useAppContext() {
|
||||||
|
// Context of the app under test.
|
||||||
|
Context appContext = InstrumentationRegistry.getTargetContext();
|
||||||
|
|
||||||
|
assertEquals("com.sbw.atrue.toolbartest", appContext.getPackageName());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.sbw.atrue.Order">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:name=".Activity.MyApplication"
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@drawable/fengmian"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
|
|
||||||
|
<!-- 将登录活动设置为程序的主活动和启动项 -->
|
||||||
|
<activity
|
||||||
|
android:name=".Activity.LoginActivity"
|
||||||
|
android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<!-- 定义了使用ToolBar控件的布局的标题为food -->
|
||||||
|
<activity
|
||||||
|
android:name=".Activity.OrderActivity"
|
||||||
|
android:label="潮汕牛肉"></activity>
|
||||||
|
<activity
|
||||||
|
android:name=".Activity.FoodActivity"
|
||||||
|
android:theme="@style/foodActivityTheme"></activity>
|
||||||
|
|
||||||
|
<!--声明其他各项活动-->
|
||||||
|
<activity android:name=".Activity.RegisterActivity" />
|
||||||
|
<activity android:name=".Activity.ShoppingActivity" />
|
||||||
|
<activity android:name=".Activity.InputActivity" />
|
||||||
|
<activity android:name=".Activity.SuccessActivity" />
|
||||||
|
<activity android:name=".Activity.ReadOrderActivity" />
|
||||||
|
<activity android:name=".Activity.MyMoneyActivity" />
|
||||||
|
<activity android:name=".Activity.SettingActivity" />
|
||||||
|
|
||||||
|
</application>
|
||||||
|
</manifest>
|
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<litepal>
|
||||||
|
<dbname value="order" ></dbname>
|
||||||
|
<version value="8" ></version>
|
||||||
|
<list>
|
||||||
|
<mapping class="com.sbw.atrue.Order.Entity.ProductOrder"></mapping>
|
||||||
|
<mapping class="com.sbw.atrue.Order.Entity.Order"></mapping>
|
||||||
|
</list>
|
||||||
|
</litepal>
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.sbw.atrue.Order.Activity;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class Connection {
|
||||||
|
private static final String TAG = "mysql11111";
|
||||||
|
java.sql.Connection conn=null;
|
||||||
|
public static void mymysql(){
|
||||||
|
final Thread thread =new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
while (!Thread.interrupted()) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100); // 每隔0.1秒尝试连接
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.e(TAG, e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1.加载JDBC驱动
|
||||||
|
try {
|
||||||
|
Class.forName("com.mysql.jdbc.Driver");
|
||||||
|
Log.v(TAG, "加载JDBC驱动成功");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
Log.e(TAG, "加载JDBC驱动失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.设置好IP/端口/数据库名/用户名/密码等必要的连接信息
|
||||||
|
String ip = "10.11.41.175";
|
||||||
|
int port = 3306;
|
||||||
|
String dbName = "mysql";
|
||||||
|
String url = "jdbc:mysql://" + ip + ":" + port
|
||||||
|
+ "/" + dbName+"?useUnicode=true&characterEncoding=utf-8&useSSL=false";
|
||||||
|
// 构建连接mysql的字符串
|
||||||
|
String user = "root";
|
||||||
|
String password = "lyx123";
|
||||||
|
|
||||||
|
// 3.连接JDBC
|
||||||
|
try {
|
||||||
|
java.sql.Connection conn = DriverManager.getConnection(url, user, password);
|
||||||
|
Log.d(TAG, "数据库连接成功");
|
||||||
|
conn.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
Log.e(TAG, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.sbw.atrue.Order.Activity;
|
||||||
|
|
||||||
|
|
||||||
|
import com.yanzhenjie.nohttp.InitializationConfig;
|
||||||
|
import com.yanzhenjie.nohttp.NoHttp;
|
||||||
|
|
||||||
|
import org.litepal.LitePalApplication;
|
||||||
|
|
||||||
|
public class MyApplication extends LitePalApplication {
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
InitializationConfig config = InitializationConfig.newBuilder(this)
|
||||||
|
.connectionTimeout(30 * 1000)
|
||||||
|
.readTimeout(30 * 1000)
|
||||||
|
.retry(10)
|
||||||
|
.build();
|
||||||
|
NoHttp.initialize(config);
|
||||||
|
Connection.mymysql();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
package com.sbw.atrue.Order.Activity;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.sbw.atrue.Order.R;
|
||||||
|
import com.sbw.atrue.Order.Util.HttpUtil;
|
||||||
|
import com.sbw.atrue.Order.Util.ShareUtils;
|
||||||
|
import com.yanzhenjie.nohttp.NoHttp;
|
||||||
|
import com.yanzhenjie.nohttp.RequestMethod;
|
||||||
|
import com.yanzhenjie.nohttp.rest.OnResponseListener;
|
||||||
|
import com.yanzhenjie.nohttp.rest.Request;
|
||||||
|
import com.yanzhenjie.nohttp.rest.RequestQueue;
|
||||||
|
import com.yanzhenjie.nohttp.rest.Response;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FileName: MyMoneyActivity <br>
|
||||||
|
* Description: <br>
|
||||||
|
* Author: 沈滨伟-13042299081 <br>
|
||||||
|
* Date: 2019/4/12 16:51
|
||||||
|
*/
|
||||||
|
public class MyMoneyActivity extends Activity {
|
||||||
|
//账户余额显示文字控件
|
||||||
|
private TextView myMoney;
|
||||||
|
private Button btnSure;
|
||||||
|
private Button btnsaveMoney;
|
||||||
|
private int nowMoney;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.my_money);
|
||||||
|
myMoney = (TextView) findViewById(R.id.my_money);
|
||||||
|
btnSure = (Button) findViewById(R.id.btn_Sure);
|
||||||
|
btnsaveMoney = (Button) findViewById(R.id.btn_SaveMoney);
|
||||||
|
//读取本地文件中的账户余额
|
||||||
|
nowMoney = ShareUtils.getInt(MyMoneyActivity.this, "money", 1);
|
||||||
|
myMoney.setText(String.valueOf(nowMoney));
|
||||||
|
|
||||||
|
//给确定按钮设置点击事件
|
||||||
|
btnSure.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
//结束当前界面,将自动返回系统上一级未被销毁的活动!比如结账活动或者主页面活动
|
||||||
|
MyMoneyActivity.this.finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//给充值按钮设置点击事件
|
||||||
|
btnsaveMoney.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
|
||||||
|
String postUrl = HttpUtil.HOST + "api/user/addMoney";
|
||||||
|
//1.创建一个队列
|
||||||
|
RequestQueue queue = NoHttp.newRequestQueue();
|
||||||
|
//2.创建消息请求 参数1:String字符串,传网址 参数2:请求方式
|
||||||
|
final Request<JSONObject> request = NoHttp.createJsonObjectRequest(postUrl, RequestMethod.POST);
|
||||||
|
//3.利用队列去添加消息请求
|
||||||
|
//使用request对象添加上传的对象添加键与值,post方式添加上传的数据
|
||||||
|
request.add("userId", ShareUtils.getInt(getApplicationContext(), "user_id", 0));
|
||||||
|
|
||||||
|
queue.add(1, request, new OnResponseListener<JSONObject>() {
|
||||||
|
@Override
|
||||||
|
public void onStart(int what) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSucceed(int what, Response<JSONObject> response) {
|
||||||
|
JSONObject res = response.get();
|
||||||
|
try {
|
||||||
|
if (res.getInt("status") == 0) {
|
||||||
|
int data = res.getInt("data");
|
||||||
|
ShareUtils.putInt(MyMoneyActivity.this, "money", data);
|
||||||
|
myMoney.setText(String.valueOf(data));
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailed(int what, Response<JSONObject> response) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish(int what) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,186 @@
|
|||||||
|
package com.sbw.atrue.Order.Activity;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.sbw.atrue.Order.R;
|
||||||
|
import com.sbw.atrue.Order.Util.HttpUtil;
|
||||||
|
import com.sbw.atrue.Order.Util.ShareUtils;
|
||||||
|
import com.yanzhenjie.nohttp.NoHttp;
|
||||||
|
import com.yanzhenjie.nohttp.RequestMethod;
|
||||||
|
import com.yanzhenjie.nohttp.rest.OnResponseListener;
|
||||||
|
import com.yanzhenjie.nohttp.rest.Request;
|
||||||
|
import com.yanzhenjie.nohttp.rest.RequestQueue;
|
||||||
|
import com.yanzhenjie.nohttp.rest.Response;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
|
||||||
|
public class RegisterActivity extends Activity {
|
||||||
|
|
||||||
|
private EditText etUsername; //用户名输入框
|
||||||
|
private EditText etPassword; //密码输入框
|
||||||
|
private EditText etPassAgain; //第二次密码输入框
|
||||||
|
private TextView tvNameWrong; //用户名错误提示文字
|
||||||
|
private TextView tvPssWrong; //密码错误提示文字
|
||||||
|
private TextView tvPssNotMatch; //密码错误提示文字
|
||||||
|
private Button btnRegister; //注册按钮
|
||||||
|
private Button btnLogin; //登录按钮
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_register);
|
||||||
|
initViews(); //初始化页面控件
|
||||||
|
initEvents(); //初始化控件事件
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化页面控件
|
||||||
|
private void initViews() {
|
||||||
|
etUsername = (EditText) findViewById(R.id.et_username);
|
||||||
|
etPassword = (EditText) findViewById(R.id.et_password);
|
||||||
|
etPassAgain = (EditText) findViewById(R.id.et_pass_again);
|
||||||
|
tvNameWrong = (TextView) findViewById(R.id.tv_name_wrong);
|
||||||
|
tvPssWrong = (TextView) findViewById(R.id.tv_pass_wrong);
|
||||||
|
tvPssNotMatch = (TextView) findViewById(R.id.tv_pass_not_match);
|
||||||
|
btnRegister = (Button) findViewById(R.id.btn_register);
|
||||||
|
btnLogin = (Button) findViewById(R.id.btn_login);
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化控件事件
|
||||||
|
private void initEvents() {
|
||||||
|
//给登陆按钮设置点击事件
|
||||||
|
btnLogin.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
//跳转到登陆界面
|
||||||
|
startActivity(new Intent(RegisterActivity.this, LoginActivity.class));
|
||||||
|
RegisterActivity.this.finish(); //结束当前界面
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//给注册按钮设置点击事件
|
||||||
|
btnRegister.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
//获取用户名输入框中的内容
|
||||||
|
String username = etUsername.getText().toString();
|
||||||
|
//获取密码输入框中的内容
|
||||||
|
String password = etPassword.getText().toString();
|
||||||
|
//获取再次输入密码输入框中的内容
|
||||||
|
String passAgain = etPassAgain.getText().toString();
|
||||||
|
|
||||||
|
//判断用户名和密码是否正确
|
||||||
|
if (!TextUtils.isEmpty(username)
|
||||||
|
&& !TextUtils.isEmpty(password)
|
||||||
|
&& !TextUtils.isEmpty(passAgain)
|
||||||
|
&& password.equals(passAgain)) { //用户名和密码都不为空且两次密码相同
|
||||||
|
|
||||||
|
hideNameAndPassError(); //隐藏用户名和密码错误提示
|
||||||
|
tryToRegister(username, password); //尝试登陆
|
||||||
|
|
||||||
|
} else { //用户名或密码为空或两次密码不同
|
||||||
|
showNameOrPassError(username, password, passAgain); //显示用户名或密码错误文字提示
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//隐藏用户名和密码错误提示
|
||||||
|
private void hideNameAndPassError() {
|
||||||
|
tvNameWrong.setVisibility(View.INVISIBLE); //隐藏用户名不能为空提示文字
|
||||||
|
tvPssWrong.setVisibility(View.INVISIBLE); //隐藏不能为空提示文字
|
||||||
|
tvPssNotMatch.setVisibility(View.INVISIBLE); //隐藏两次密码不一致提示文字
|
||||||
|
}
|
||||||
|
|
||||||
|
//尝试登陆
|
||||||
|
private void tryToRegister(final String username, final String password) {
|
||||||
|
String postUrl = HttpUtil.HOST + "api/user/register";
|
||||||
|
//1.创建一个队列
|
||||||
|
RequestQueue queue = NoHttp.newRequestQueue();
|
||||||
|
//2.创建消息请求 参数1:String字符串,传网址 参数2:请求方式
|
||||||
|
final Request<JSONObject> request = NoHttp.createJsonObjectRequest(postUrl, RequestMethod.POST);
|
||||||
|
//3.利用队列去添加消息请求
|
||||||
|
//使用request对象添加上传的对象添加键与值,post方式添加上传的数据
|
||||||
|
request.add("username", username);
|
||||||
|
request.add("password", password);
|
||||||
|
|
||||||
|
queue.add(1, request, new OnResponseListener<JSONObject>() {
|
||||||
|
@Override
|
||||||
|
public void onStart(int what) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSucceed(int what, Response<JSONObject> response) {
|
||||||
|
JSONObject res = response.get();
|
||||||
|
try {
|
||||||
|
if (res.getInt("status") == 0) {
|
||||||
|
JSONObject data = res.getJSONObject("data");
|
||||||
|
Toast.makeText(getApplicationContext(), "成功注册用户:" + username, Toast.LENGTH_SHORT).show();
|
||||||
|
//跳转到商品购买页面
|
||||||
|
startActivity(new Intent(RegisterActivity.this, LoginActivity.class));
|
||||||
|
finish();
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getApplicationContext(), "用户名已存在", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailed(int what, Response<JSONObject> response) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish(int what) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//获取数据库中该用户名对应的密码
|
||||||
|
String realPassword = ShareUtils.getString(this, username, "");
|
||||||
|
if ("".equals(realPassword)) { //数据库中没有该用户名的数据
|
||||||
|
|
||||||
|
} else { //该用户名已存在数据库中
|
||||||
|
//提示用户名已存在
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示用户名或密码错误文字提示
|
||||||
|
*
|
||||||
|
* @param username 输入的用户名
|
||||||
|
* @param password 输入的密码
|
||||||
|
* @param passAgain 再次输入的密码
|
||||||
|
*/
|
||||||
|
private void showNameOrPassError(String username, String password, String passAgain) {
|
||||||
|
if (TextUtils.isEmpty(username)) { //用户名为空
|
||||||
|
tvNameWrong.setVisibility(View.VISIBLE); //显示用户名错误提示文字
|
||||||
|
} else { //用户名不为空
|
||||||
|
tvNameWrong.setVisibility(View.INVISIBLE); //用户名错误提示文字消失
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(password)) { //密码为空
|
||||||
|
tvPssWrong.setVisibility(View.VISIBLE); //显示密码错误提示文字
|
||||||
|
} else { //密码不为空
|
||||||
|
tvPssWrong.setVisibility(View.INVISIBLE); //密码错误提示文字消失
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!password.equals(passAgain)) { //两次输入的密码不同
|
||||||
|
tvPssNotMatch.setVisibility(View.VISIBLE); //显示两次密码输入不一致提示
|
||||||
|
} else { //两次输入的密码相同
|
||||||
|
tvPssNotMatch.setVisibility(View.INVISIBLE); //两次密码输入不一致提示消失
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
package com.sbw.atrue.Order.Activity;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import com.sbw.atrue.Order.R;
|
||||||
|
import com.sbw.atrue.Order.Util.HttpUtil;
|
||||||
|
import com.sbw.atrue.Order.Util.ShareUtils;
|
||||||
|
import com.yanzhenjie.nohttp.NoHttp;
|
||||||
|
import com.yanzhenjie.nohttp.RequestMethod;
|
||||||
|
import com.yanzhenjie.nohttp.rest.OnResponseListener;
|
||||||
|
import com.yanzhenjie.nohttp.rest.Request;
|
||||||
|
import com.yanzhenjie.nohttp.rest.RequestQueue;
|
||||||
|
import com.yanzhenjie.nohttp.rest.Response;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FileName: SettingActivity <br>
|
||||||
|
* Description: <br>
|
||||||
|
* Author: 沈滨伟-13042299081 <br>
|
||||||
|
* Date: 2019/4/12 20:55
|
||||||
|
*/
|
||||||
|
public class SettingActivity extends Activity {
|
||||||
|
private EditText etname; //姓名输入框
|
||||||
|
private EditText etPhone; //手机号输入框
|
||||||
|
private EditText etMail; //邮箱输入框
|
||||||
|
private Button btnInputCompleted; //输入完成按钮
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.person_setting);
|
||||||
|
etname = (EditText) findViewById(R.id.et_name);
|
||||||
|
etPhone = (EditText) findViewById(R.id.et_phone);
|
||||||
|
etMail = (EditText) findViewById(R.id.et_mail);
|
||||||
|
btnInputCompleted = (Button) findViewById(R.id.btn_input_completed);
|
||||||
|
//登录时默认自动在本地保存了一份客户信息,将其读取出来并显示
|
||||||
|
etname.setText(ShareUtils.getString(this, "user_true_name", ""));
|
||||||
|
etPhone.setText(ShareUtils.getString(this, "user_true_phone", ""));
|
||||||
|
etMail.setText(ShareUtils.getString(this, "user_true_mail", ""));
|
||||||
|
btnInputCompleted.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
|
||||||
|
|
||||||
|
String postUrl = HttpUtil.HOST + "api/user/updateUser";
|
||||||
|
//1.创建一个队列
|
||||||
|
RequestQueue queue = NoHttp.newRequestQueue();
|
||||||
|
//2.创建消息请求 参数1:String字符串,传网址 参数2:请求方式
|
||||||
|
final Request<JSONObject> request = NoHttp.createJsonObjectRequest(postUrl, RequestMethod.POST);
|
||||||
|
//3.利用队列去添加消息请求
|
||||||
|
//使用request对象添加上传的对象添加键与值,post方式添加上传的数据
|
||||||
|
request.add("id", ShareUtils.getInt(getApplicationContext(), "user_id", 0));
|
||||||
|
request.add("nickname", etname.getText().toString());
|
||||||
|
request.add("phone", etPhone.getText().toString());
|
||||||
|
request.add("email", etMail.getText().toString());
|
||||||
|
|
||||||
|
queue.add(1, request, new OnResponseListener<JSONObject>() {
|
||||||
|
@Override
|
||||||
|
public void onStart(int what) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSucceed(int what, Response<JSONObject> response) {
|
||||||
|
JSONObject res = response.get();
|
||||||
|
try {
|
||||||
|
if (res.getInt("status") == 0) {
|
||||||
|
//保存用户新设置的客户个人信息
|
||||||
|
ShareUtils.putString(SettingActivity.this, "user_true_name", etname.getText().toString());
|
||||||
|
ShareUtils.putString(SettingActivity.this, "user_true_phone", etPhone.getText().toString());
|
||||||
|
ShareUtils.putString(SettingActivity.this, "user_true_mail", etMail.getText().toString());
|
||||||
|
//登录成功,跳转到菜单展示的主页面
|
||||||
|
Intent intent = new Intent(SettingActivity.this, OrderActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailed(int what, Response<JSONObject> response) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish(int what) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
package com.sbw.atrue.Order.Entity;
|
||||||
|
|
||||||
|
import org.litepal.crud.DataSupport;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FileName: Order <br>
|
||||||
|
* Description: 订单类 <br>
|
||||||
|
* Author: 沈滨伟-13042299081 <br>
|
||||||
|
* Date: 2019/4/8 15:25
|
||||||
|
*/
|
||||||
|
public class Order extends DataSupport {
|
||||||
|
private int id; //订单ID
|
||||||
|
private List<ProductOrder> selectedProducts; //被选择的的商品数据
|
||||||
|
private double totalPrice;//该订单的总价
|
||||||
|
private String userName;//客户姓名
|
||||||
|
private String phone;//客户电话
|
||||||
|
private String tableId;//用餐桌号
|
||||||
|
private String time;//下单时间
|
||||||
|
private boolean ispay;//是否已结账
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProductOrder> getSelectedProducts() {
|
||||||
|
return selectedProducts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getTotalPrice() {
|
||||||
|
return totalPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName() {
|
||||||
|
return userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTableId() {
|
||||||
|
return tableId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isIspay() {
|
||||||
|
return ispay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelectedProducts(List<ProductOrder> selectedProducts) {
|
||||||
|
this.selectedProducts = selectedProducts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalPrice(double totalPrice) {
|
||||||
|
this.totalPrice = totalPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserName(String userName) {
|
||||||
|
this.userName = userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhone(String phone) {
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTableId(String tableId) {
|
||||||
|
this.tableId = tableId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(String time) {
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIspay(boolean ispay) {
|
||||||
|
this.ispay = ispay;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,152 @@
|
|||||||
|
package com.sbw.atrue.Order.Entity;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
//商品类
|
||||||
|
public class Product implements Parcelable {
|
||||||
|
private int id; //商品表示符
|
||||||
|
private String name; //商品名
|
||||||
|
private double price; //价格
|
||||||
|
private String picture; //商品图片
|
||||||
|
private int sale; //月销量
|
||||||
|
private String shopName; //店铺名称
|
||||||
|
private String detail; //产品描述
|
||||||
|
private int selectedCount = 0; //已选择该商品的数量
|
||||||
|
private boolean isShowSubBtn; //是否显示减去按钮
|
||||||
|
|
||||||
|
public Product(int id, String name, double price, String picture, int sale, String shopName, String detail, boolean isShowSubBtn) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.price = price;
|
||||||
|
this.picture = picture;
|
||||||
|
this.sale = sale;
|
||||||
|
this.shopName = shopName;
|
||||||
|
this.detail = detail;
|
||||||
|
this.isShowSubBtn = isShowSubBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取该商品被选中的次数
|
||||||
|
public int getSelectedCount() {
|
||||||
|
return selectedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
//将商品被选中次数清零与设置不显示减去按钮
|
||||||
|
public void clearZero() {
|
||||||
|
selectedCount = 0;
|
||||||
|
isShowSubBtn = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//增加该商品被选中的次数
|
||||||
|
public void addSelectedCount() {
|
||||||
|
selectedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//减少该商品被选中的次数
|
||||||
|
public void subSelectedCount() {
|
||||||
|
if (selectedCount > 0) {
|
||||||
|
selectedCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取该商品的id
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取该商品的名字
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取该商品的价格
|
||||||
|
public double getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取该商品的图片
|
||||||
|
public String getPicture() {
|
||||||
|
return picture;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取该商品的月销量
|
||||||
|
public int getSale() {
|
||||||
|
return sale;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取该商品的店铺名
|
||||||
|
public String getShopName() {
|
||||||
|
return shopName;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取该商品的详情
|
||||||
|
public String getDetail() {
|
||||||
|
return detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取是否显示减去按钮
|
||||||
|
public boolean getIsShowSubBtn() {
|
||||||
|
return isShowSubBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置是否显示减去按钮
|
||||||
|
public void setIsShowSubBtn(boolean isShowSubBtn) {
|
||||||
|
this.isShowSubBtn = isShowSubBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Product[ name=" + name + ",price=" + price + ",picture=" + picture
|
||||||
|
+ ",sale=" + sale + ",shopName=" + shopName + ",detail=" + detail + ",selectedCount=" + selectedCount + " ]";
|
||||||
|
}
|
||||||
|
|
||||||
|
//以下是实现Parcelable自动生成的内容
|
||||||
|
protected Product(Parcel in) {
|
||||||
|
id = in.readInt();
|
||||||
|
name = in.readString();
|
||||||
|
price = in.readDouble();
|
||||||
|
picture = in.readString();
|
||||||
|
sale = in.readInt();
|
||||||
|
shopName = in.readString();
|
||||||
|
detail = in.readString();
|
||||||
|
selectedCount = in.readInt();
|
||||||
|
isShowSubBtn = in.readByte() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<Product> CREATOR = new Creator<Product>() {
|
||||||
|
@Override
|
||||||
|
public Product createFromParcel(Parcel in) {
|
||||||
|
return new Product(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Product[] newArray(int size) {
|
||||||
|
return new Product[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeInt(id);
|
||||||
|
dest.writeString(name);
|
||||||
|
dest.writeDouble(price);
|
||||||
|
dest.writeString(picture);
|
||||||
|
dest.writeInt(sale);
|
||||||
|
dest.writeString(shopName);
|
||||||
|
dest.writeString(detail);
|
||||||
|
dest.writeInt(selectedCount);
|
||||||
|
dest.writeByte((byte) (isShowSubBtn ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelctCount(int num) {
|
||||||
|
selectedCount = num;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.sbw.atrue.Order.Entity;
|
||||||
|
|
||||||
|
import org.litepal.crud.DataSupport;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FileName: ProductOrder <br>
|
||||||
|
* Description: 订单中的菜品信息类 <br>
|
||||||
|
* Author: 沈滨伟-13042299081 <br>
|
||||||
|
* Date: 2019/4/9 14:54
|
||||||
|
*/
|
||||||
|
public class ProductOrder extends DataSupport{
|
||||||
|
private int id; //订单ID
|
||||||
|
private List<Order> orders; //与Order表建立多对多关联关系
|
||||||
|
private String foodName;//菜名
|
||||||
|
private int num;//购买数量
|
||||||
|
private double price;//单项菜品总价
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Order> getOrders() {
|
||||||
|
return orders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFoodName() {
|
||||||
|
return foodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNum() {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrders(List<Order> orders) {
|
||||||
|
this.orders = orders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFoodName(String foodName) {
|
||||||
|
this.foodName = foodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNum(int num) {
|
||||||
|
this.num = num;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(double price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.sbw.atrue.Order.Util;
|
||||||
|
|
||||||
|
|
||||||
|
public class HttpUtil {
|
||||||
|
|
||||||
|
public static final String HOST = "http://coding-space.cn:9030/";
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.sbw.atrue.Order.Util;
|
||||||
|
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
public interface MyListener<T> {
|
||||||
|
void onSuccess(T data) throws JSONException;
|
||||||
|
}
|
@ -0,0 +1,185 @@
|
|||||||
|
package com.sbw.atrue.Order.Util;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.sbw.atrue.Order.Activity.ShoppingActivity;
|
||||||
|
import com.sbw.atrue.Order.R;
|
||||||
|
import com.sbw.atrue.Order.Entity.Product;
|
||||||
|
|
||||||
|
|
||||||
|
//商品列表适配器
|
||||||
|
public class ProductListAdapter extends BaseAdapter {
|
||||||
|
private Context mContext; //页面布局加载器
|
||||||
|
private List<Product> productsData; //商品内容数据源
|
||||||
|
private ArrayList<Product> selectedProducts = new ArrayList<Product>(); //被选择的的商品数据
|
||||||
|
private int totalSelectedCount = 0; //当前选择商品总数
|
||||||
|
private int totalPrice = 0; //当前选择商品总价
|
||||||
|
|
||||||
|
public ProductListAdapter(Context context, List<Product> data) {
|
||||||
|
mContext = context;
|
||||||
|
productsData = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//返回适配器内子项的数量
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return productsData.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
//返回适配器内的某个子项
|
||||||
|
@Override
|
||||||
|
public Object getItem(int position) {
|
||||||
|
return productsData.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
//返回适配器内的某个子项的id号
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
//每个子view生成都会调用的界面生成方法
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
ViewHolder viewHolder = null; //声明控件暂存器
|
||||||
|
if (convertView == null) { //如果内容界面为空
|
||||||
|
viewHolder = new ViewHolder(); //新建控件暂存器
|
||||||
|
//加载内容界面
|
||||||
|
convertView = LayoutInflater.from(mContext).inflate(R.layout.product_listview_item, null);
|
||||||
|
//绑定控件
|
||||||
|
viewHolder.picture = (ImageView) convertView.findViewById(R.id.iv_product_picture);
|
||||||
|
viewHolder.name = (TextView) convertView.findViewById(R.id.tv_product_name);
|
||||||
|
viewHolder.price = (TextView) convertView.findViewById(R.id.tv_product_pirce);
|
||||||
|
viewHolder.sale = (TextView) convertView.findViewById(R.id.tv_sale_count);
|
||||||
|
viewHolder.shopName = (TextView) convertView.findViewById(R.id.tv_product_shop_name);
|
||||||
|
viewHolder.detail = (TextView) convertView.findViewById(R.id.tv_product_detail);
|
||||||
|
viewHolder.selectedCount = (TextView) convertView.findViewById(R.id.tv_selected_count);
|
||||||
|
viewHolder.addProduct = (ImageButton) convertView.findViewById(R.id.btn_add_product);
|
||||||
|
viewHolder.subProduct = (ImageButton) convertView.findViewById(R.id.btn_sub_product);
|
||||||
|
//将控件暂存器放到内容界面中
|
||||||
|
convertView.setTag(viewHolder);
|
||||||
|
} else { //内容界面不为空
|
||||||
|
viewHolder = (ViewHolder) convertView.getTag(); //从内容界面提取出控件暂存器
|
||||||
|
}
|
||||||
|
Product product = productsData.get(position); //获取当前位置的商品
|
||||||
|
initListItem(viewHolder, product); //初始化列表界面内容
|
||||||
|
initButtonEvent(viewHolder, product); //初始化按钮的点击事件
|
||||||
|
return convertView; //返回主界面
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化列表界面内容
|
||||||
|
*
|
||||||
|
* @param viewHolder 控件暂存器
|
||||||
|
* @param product 当前位置的产品
|
||||||
|
*/
|
||||||
|
private void initListItem(final ViewHolder viewHolder, final Product product) {
|
||||||
|
// viewHolder.picture.setImageResource(product.getPicture()); //设置商品图片
|
||||||
|
Glide.with(mContext).load(product.getPicture()).into(viewHolder.picture);
|
||||||
|
viewHolder.name.setText(product.getName()); //设置商品名
|
||||||
|
viewHolder.price.setText(String.valueOf("¥" + product.getPrice())); //设置商品价格
|
||||||
|
viewHolder.sale.setText(String.valueOf("月售:" + product.getSale())); //设置商品月销售量
|
||||||
|
viewHolder.shopName.setText(product.getShopName()); //设置商家名称
|
||||||
|
viewHolder.detail.setText(product.getDetail()); //设置商品简介
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化按钮的点击事件
|
||||||
|
*
|
||||||
|
* @param viewHolder 控件暂存器
|
||||||
|
* @param product 当前位置的产品
|
||||||
|
*/
|
||||||
|
private void initButtonEvent(final ViewHolder viewHolder, final Product product) {
|
||||||
|
//给添加商品按钮添加点击事件
|
||||||
|
viewHolder.addProduct.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
totalSelectedCount++; //被选择商品总数加1
|
||||||
|
totalPrice += product.getPrice(); //被选择商品总价加上该商品的价格
|
||||||
|
product.addSelectedCount(); //商品本身的数量加1
|
||||||
|
if (!selectedProducts.contains(product)) { //如果被选择商品列表还没有该商品
|
||||||
|
selectedProducts.add(product); //将该商品加到被选择列表中
|
||||||
|
}
|
||||||
|
product.setIsShowSubBtn(true); //设置商品对应的减去按钮消失
|
||||||
|
//在被选择商品数标签上设置被选择商品数
|
||||||
|
viewHolder.selectedCount.setText(String.valueOf(product.getSelectedCount()));
|
||||||
|
//将被选择的商品总数和总价设置回购物界面
|
||||||
|
((ShoppingActivity) mContext).setSelectedCountAndPrice(totalSelectedCount, totalPrice);
|
||||||
|
//将被选择的商品列表设置回购物界面
|
||||||
|
((ShoppingActivity) mContext).setSelectedProducts(selectedProducts);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//给减去商品按钮添加点击事件
|
||||||
|
viewHolder.subProduct.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (totalSelectedCount - 1 >= 0) { //当被选择总数减1不为0时
|
||||||
|
totalSelectedCount--; //被选择商品总数减1
|
||||||
|
totalPrice -= product.getPrice(); //被选择商品总价减去该商品的价格
|
||||||
|
product.subSelectedCount(); //商品本身的数量减1
|
||||||
|
if (product.getSelectedCount() == 0) { //如果被选择商品的数量为0
|
||||||
|
|
||||||
|
product.setIsShowSubBtn(false); //设置该商品对应的减去按钮消失
|
||||||
|
selectedProducts.remove(product); //从被选择商品列表中移除该商品
|
||||||
|
}
|
||||||
|
//在被选择商品数标签上设置被选择商品数
|
||||||
|
viewHolder.selectedCount.setText(String.valueOf(product.getSelectedCount()));
|
||||||
|
//将被选择的商品总数和总价设置回购物界面
|
||||||
|
((ShoppingActivity) mContext).setSelectedCountAndPrice(totalSelectedCount, totalPrice);
|
||||||
|
//将被选择的商品列表设置回购物界面
|
||||||
|
((ShoppingActivity) mContext).setSelectedProducts(selectedProducts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//设置减去按钮的与被选择商品数量标签的可见性
|
||||||
|
setSubButtonAndSelectCount(viewHolder, product);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置减去按钮的与被选择商品数量标签的可见性
|
||||||
|
*
|
||||||
|
* @param viewHolder 控件暂存器
|
||||||
|
* @param product 当前位置的产品
|
||||||
|
*/
|
||||||
|
private void setSubButtonAndSelectCount(final ViewHolder viewHolder, Product product) {
|
||||||
|
boolean show = product.getIsShowSubBtn(); //从Map中获取是否需要展示减去按钮
|
||||||
|
viewHolder.subProduct.setVisibility(show ? View.VISIBLE : View.INVISIBLE); //设置减去商品按钮是否可见
|
||||||
|
viewHolder.selectedCount.setVisibility(show ? View.VISIBLE : View.INVISIBLE); //设置被选择商品数标签是否可见
|
||||||
|
if (show) { //需要展示减去按钮
|
||||||
|
//在被选择商品数标签上设置被选择商品数
|
||||||
|
viewHolder.selectedCount.setText(String.valueOf(product.getSelectedCount()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//设置全部商品数据
|
||||||
|
public void setSelectedProducts(ArrayList<Product> selectedProducts) {
|
||||||
|
this.selectedProducts = selectedProducts; //设置被选择的商品
|
||||||
|
notifyDataSetChanged(); //通知系统数据改变
|
||||||
|
}
|
||||||
|
|
||||||
|
//控件暂存器
|
||||||
|
static class ViewHolder {
|
||||||
|
ImageView picture; //商品图片
|
||||||
|
TextView name; //商品名
|
||||||
|
TextView price; //商品价格
|
||||||
|
TextView sale; //月销量
|
||||||
|
TextView shopName; //商店名
|
||||||
|
TextView detail; //商品细节
|
||||||
|
TextView selectedCount; //选择商品的数量
|
||||||
|
ImageButton addProduct; //添加商品按钮
|
||||||
|
ImageButton subProduct; //减去商品按钮
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package com.sbw.atrue.Order.Util;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SharedPreferences工具类
|
||||||
|
*/
|
||||||
|
public class ShareUtils {
|
||||||
|
public static final String NAME = "config";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存入字符串
|
||||||
|
* @param mContext 上下文
|
||||||
|
* @param key 关键字
|
||||||
|
* @param value 传入的值
|
||||||
|
*/
|
||||||
|
public static void putString(Context mContext, String key, String value) {
|
||||||
|
getSP(mContext).edit().putString(key, value).commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void putInt(Context mContext, String key, int value) {
|
||||||
|
getSP(mContext).edit().putInt(key,value).commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取字符串
|
||||||
|
* @param mContext 上下文
|
||||||
|
* @param key 关键字
|
||||||
|
* @param defValue 默认返回值
|
||||||
|
*/
|
||||||
|
public static String getString(Context mContext, String key, String defValue) {
|
||||||
|
return getSP(mContext).getString(key, defValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getInt(Context mContext, String key, int defValue) {
|
||||||
|
return getSP(mContext).getInt(key, defValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回一个根据上下文生成的SharedPreferences
|
||||||
|
* @param mContext 上下文
|
||||||
|
* @return 根据上下文生成的SharedPreferences
|
||||||
|
*/
|
||||||
|
private static SharedPreferences getSP(Context mContext) {
|
||||||
|
return mContext.getSharedPreferences(NAME, Context.MODE_PRIVATE);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package franzliszt;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
|
|
||||||
|
public class SP {
|
||||||
|
private static SP spInstant;
|
||||||
|
private String defaultModelName;
|
||||||
|
public SP(){
|
||||||
|
|
||||||
|
}
|
||||||
|
public SP(Context context){
|
||||||
|
if (spInstant == null){
|
||||||
|
spInstant = new SP( );
|
||||||
|
spInstant.defaultModelName = "DefaultModelName";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void PutData(Context context, String key, Object value){
|
||||||
|
PutData( context,defaultModelName,key,value );
|
||||||
|
}
|
||||||
|
private void PutData(Context context, String defaultModelName , String key, Object value){
|
||||||
|
SharedPreferences preferences = context.getSharedPreferences( defaultModelName, Context.MODE_PRIVATE );
|
||||||
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
if (value instanceof Boolean){
|
||||||
|
editor.putBoolean( key,(Boolean) value );
|
||||||
|
}else if (value instanceof Integer){
|
||||||
|
editor.putInt( key,(Integer)value );
|
||||||
|
}else if (value instanceof Float){
|
||||||
|
editor.putFloat( key,(Float)value );
|
||||||
|
}else if (value instanceof Long){
|
||||||
|
editor.putLong( key,(Long)value );
|
||||||
|
}else if (value instanceof String){
|
||||||
|
editor.putString( key,(String)value );
|
||||||
|
}else{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
public Object GetData(Context context, String key, Object defaultValue){
|
||||||
|
return GetData( context,defaultModelName,key,defaultValue);
|
||||||
|
}
|
||||||
|
private Object GetData(Context context, String defaultModelName, String key, Object defaultValue){
|
||||||
|
SharedPreferences preferences = context.getSharedPreferences( defaultModelName, Context.MODE_PRIVATE );
|
||||||
|
if (defaultValue instanceof Boolean){
|
||||||
|
return preferences.getBoolean( key,(Boolean) defaultValue );
|
||||||
|
}else if (defaultValue instanceof Integer){
|
||||||
|
return preferences.getInt( key,(Integer) defaultValue );
|
||||||
|
}else if (defaultValue instanceof Float){
|
||||||
|
return preferences.getFloat( key,(Float) defaultValue );
|
||||||
|
}else if (defaultValue instanceof Long){
|
||||||
|
return preferences.getLong( key,(Long) defaultValue );
|
||||||
|
}else if (defaultValue instanceof String){
|
||||||
|
return preferences.getString( key,(String) defaultValue );
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,208 @@
|
|||||||
|
package franzliszt.foodturntable;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import com.franzliszt.foodturntable.animator.ViewAnimator;
|
||||||
|
import com.franzliszt.foodturntable.component.InitialCenterCircleView;
|
||||||
|
import com.franzliszt.foodturntable.component.MainCircleView;
|
||||||
|
import com.franzliszt.foodturntable.component.PercentIndicatorView;
|
||||||
|
import com.franzliszt.foodturntable.component.RightCircleView;
|
||||||
|
import com.franzliszt.foodturntable.component.SideArcsView;
|
||||||
|
import com.franzliszt.foodturntable.component.TopCircleBorderView;
|
||||||
|
import com.franzliszt.foodturntable.component.finish.FinishedFailureView;
|
||||||
|
import com.franzliszt.foodturntable.component.finish.FinishedOkView;
|
||||||
|
import com.sbw.atrue.Order.R;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jlmd
|
||||||
|
*/
|
||||||
|
public class AnimatedCircleLoadingView extends FrameLayout {
|
||||||
|
|
||||||
|
private static final String DEFAULT_HEX_MAIN_COLOR = "#FF9A00";
|
||||||
|
private static final String DEFAULT_HEX_SECONDARY_COLOR = "#BDBDBD";
|
||||||
|
private static final String DEFAULT_HEX_TINT_COLOR = "#FFFFFF";
|
||||||
|
private static final String DEFAULT_HEX_TEXT_COLOR = "#FFFFFF";
|
||||||
|
private final Context context;
|
||||||
|
private InitialCenterCircleView initialCenterCircleView;
|
||||||
|
private MainCircleView mainCircleView;
|
||||||
|
private RightCircleView rightCircleView;
|
||||||
|
private SideArcsView sideArcsView;
|
||||||
|
private TopCircleBorderView topCircleBorderView;
|
||||||
|
private FinishedOkView finishedOkView;
|
||||||
|
private FinishedFailureView finishedFailureView;
|
||||||
|
private PercentIndicatorView percentIndicatorView;
|
||||||
|
private ViewAnimator viewAnimator;
|
||||||
|
private AnimationListener animationListener;
|
||||||
|
private boolean startAnimationIndeterminate;
|
||||||
|
private boolean startAnimationDeterminate;
|
||||||
|
private boolean stopAnimationOk;
|
||||||
|
private boolean stopAnimationFailure;
|
||||||
|
private int mainColor;
|
||||||
|
private int secondaryColor;
|
||||||
|
private int checkMarkTintColor;
|
||||||
|
private int failureMarkTintColor;
|
||||||
|
private int textColor;
|
||||||
|
|
||||||
|
public AnimatedCircleLoadingView(Context context) {
|
||||||
|
super(context);
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimatedCircleLoadingView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
this.context = context;
|
||||||
|
initAttributes(attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimatedCircleLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
this.context = context;
|
||||||
|
initAttributes(attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initAttributes(AttributeSet attrs) {
|
||||||
|
TypedArray attributes =
|
||||||
|
getContext().obtainStyledAttributes(attrs, R.styleable.AnimatedCircleLoadingView);
|
||||||
|
mainColor = attributes.getColor(R.styleable.AnimatedCircleLoadingView_animCircleLoadingView_mainColor,
|
||||||
|
Color.parseColor(DEFAULT_HEX_MAIN_COLOR));
|
||||||
|
secondaryColor = attributes.getColor(R.styleable.AnimatedCircleLoadingView_animCircleLoadingView_secondaryColor,
|
||||||
|
Color.parseColor(DEFAULT_HEX_SECONDARY_COLOR));
|
||||||
|
checkMarkTintColor =
|
||||||
|
attributes.getColor(R.styleable.AnimatedCircleLoadingView_animCircleLoadingView_checkMarkTintColor,
|
||||||
|
Color.parseColor(DEFAULT_HEX_TINT_COLOR));
|
||||||
|
failureMarkTintColor =
|
||||||
|
attributes.getColor(R.styleable.AnimatedCircleLoadingView_animCircleLoadingView_failureMarkTintColor,
|
||||||
|
Color.parseColor(DEFAULT_HEX_TINT_COLOR));
|
||||||
|
textColor = attributes.getColor(R.styleable.AnimatedCircleLoadingView_animCircleLoadingView_textColor,
|
||||||
|
Color.parseColor(DEFAULT_HEX_TEXT_COLOR));
|
||||||
|
attributes.recycle();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||||
|
super.onSizeChanged(w, h, oldw, oldh);
|
||||||
|
init();
|
||||||
|
startAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startAnimation() {
|
||||||
|
if (getWidth() != 0 && getHeight() != 0) {
|
||||||
|
if (startAnimationIndeterminate) {
|
||||||
|
viewAnimator.startAnimator();
|
||||||
|
startAnimationIndeterminate = false;
|
||||||
|
}
|
||||||
|
if (startAnimationDeterminate) {
|
||||||
|
addView(percentIndicatorView);
|
||||||
|
viewAnimator.startAnimator();
|
||||||
|
startAnimationDeterminate = false;
|
||||||
|
}
|
||||||
|
if (stopAnimationOk) {
|
||||||
|
stopOk();
|
||||||
|
}
|
||||||
|
if (stopAnimationFailure) {
|
||||||
|
stopFailure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
// Force view to be a square
|
||||||
|
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
initComponents();
|
||||||
|
addComponentsViews();
|
||||||
|
initAnimatorHelper();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initComponents() {
|
||||||
|
int width = getWidth();
|
||||||
|
initialCenterCircleView =
|
||||||
|
new InitialCenterCircleView(context, width, mainColor, secondaryColor);
|
||||||
|
rightCircleView = new RightCircleView(context, width, mainColor, secondaryColor);
|
||||||
|
sideArcsView = new SideArcsView(context, width, mainColor, secondaryColor);
|
||||||
|
topCircleBorderView = new TopCircleBorderView(context, width, mainColor, secondaryColor);
|
||||||
|
mainCircleView = new MainCircleView(context, width, mainColor, secondaryColor);
|
||||||
|
finishedOkView =
|
||||||
|
new FinishedOkView(context, width, mainColor, secondaryColor, checkMarkTintColor);
|
||||||
|
finishedFailureView =
|
||||||
|
new FinishedFailureView(context, width, mainColor, secondaryColor, failureMarkTintColor);
|
||||||
|
percentIndicatorView = new PercentIndicatorView(context, width, textColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addComponentsViews() {
|
||||||
|
addView(initialCenterCircleView);
|
||||||
|
addView(rightCircleView);
|
||||||
|
addView(sideArcsView);
|
||||||
|
addView(topCircleBorderView);
|
||||||
|
addView(mainCircleView);
|
||||||
|
addView(finishedOkView);
|
||||||
|
addView(finishedFailureView);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initAnimatorHelper() {
|
||||||
|
viewAnimator = new ViewAnimator();
|
||||||
|
viewAnimator.setAnimationListener(animationListener);
|
||||||
|
viewAnimator.setComponentViewAnimations(initialCenterCircleView, rightCircleView, sideArcsView,
|
||||||
|
topCircleBorderView, mainCircleView, finishedOkView, finishedFailureView,
|
||||||
|
percentIndicatorView);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startIndeterminate() {
|
||||||
|
startAnimationIndeterminate = true;
|
||||||
|
startAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startDeterminate() {
|
||||||
|
startAnimationDeterminate = true;
|
||||||
|
startAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPercent(int percent) {
|
||||||
|
if (percentIndicatorView != null) {
|
||||||
|
percentIndicatorView.setPercent(percent);
|
||||||
|
if (percent == 100) {
|
||||||
|
viewAnimator.finishOk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopOk() {
|
||||||
|
if (viewAnimator == null) {
|
||||||
|
stopAnimationOk = true;
|
||||||
|
} else {
|
||||||
|
viewAnimator.finishOk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopFailure() {
|
||||||
|
if (viewAnimator == null) {
|
||||||
|
stopAnimationFailure = true;
|
||||||
|
} else {
|
||||||
|
viewAnimator.finishFailure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetLoading() {
|
||||||
|
if (viewAnimator != null) {
|
||||||
|
viewAnimator.resetAnimator();
|
||||||
|
}
|
||||||
|
setPercent(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAnimationListener(AnimationListener animationListener) {
|
||||||
|
this.animationListener = animationListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface AnimationListener {
|
||||||
|
|
||||||
|
void onAnimationEnd(boolean success);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,160 @@
|
|||||||
|
package franzliszt.foodturntable;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewAnimationUtils;
|
||||||
|
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.RadioGroup;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.sbw.atrue.Order.R;
|
||||||
|
|
||||||
|
import franzliszt.SP;
|
||||||
|
|
||||||
|
public class MainTTActivity extends AppCompatActivity {
|
||||||
|
private AnimatedCircleLoadingView loadingView;
|
||||||
|
private Turntable turntable;
|
||||||
|
private int count = 0;
|
||||||
|
private ImageView ChangeStatus;
|
||||||
|
private RadioGroup RG;
|
||||||
|
private SP sp;
|
||||||
|
private Context context = null;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate( savedInstanceState );
|
||||||
|
if (Build.VERSION.SDK_INT >= 21) {
|
||||||
|
View decorView = getWindow().getDecorView();
|
||||||
|
decorView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE );
|
||||||
|
getWindow().setStatusBarColor( Color.TRANSPARENT );
|
||||||
|
}
|
||||||
|
setContentView( R.layout.activity_tmain );
|
||||||
|
InitView();
|
||||||
|
SelectNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitView() {
|
||||||
|
turntable = findViewById( R.id.TurnTable );
|
||||||
|
loadingView = findViewById( R.id.loadingView );
|
||||||
|
ChangeStatus = findViewById( R.id.StartAndEnd );
|
||||||
|
RG = findViewById( R.id.RG );
|
||||||
|
/*默认设置8等份*/
|
||||||
|
turntable.InitNumber( 8 );
|
||||||
|
if (context == null) {
|
||||||
|
context = MainTTActivity.this;
|
||||||
|
}
|
||||||
|
sp = new SP( context );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start(View view) {
|
||||||
|
count++;
|
||||||
|
/*暂停*/
|
||||||
|
if (count % 2 == 0) {
|
||||||
|
turntable.Stop();
|
||||||
|
StartIcon();
|
||||||
|
} else {
|
||||||
|
/*开始*/
|
||||||
|
turntable.Start( -1 );
|
||||||
|
StopIcon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartIcon() {
|
||||||
|
ChangeStatus.setImageDrawable( getResources().getDrawable( R.drawable.start ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StopIcon() {
|
||||||
|
ChangeStatus.setImageDrawable( getResources().getDrawable( R.drawable.stop ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Confirm(View view) {
|
||||||
|
RevealAnim( view );
|
||||||
|
loadingView.setVisibility( View.VISIBLE );
|
||||||
|
startLoading();
|
||||||
|
startPercentMockThread();
|
||||||
|
int num = (int) sp.GetData( context, "num", 0 );
|
||||||
|
turntable.InitNumber( num );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset(View view) {
|
||||||
|
RevealAnim( view );
|
||||||
|
loadingView.setVisibility( View.GONE );
|
||||||
|
resetLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startLoading() {
|
||||||
|
loadingView.startIndeterminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startPercentMockThread() {
|
||||||
|
Runnable runnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Thread.sleep( 500 );
|
||||||
|
for (int i = 0; i <= 100; i++) {
|
||||||
|
Thread.sleep( 40 );
|
||||||
|
changePercent( i );
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new Thread(runnable).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changePercent(final int percent) {
|
||||||
|
runOnUiThread( new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
loadingView.setPercent( percent );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetLoading() {
|
||||||
|
runOnUiThread( new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
loadingView.resetLoading();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RevealAnim(View view) {
|
||||||
|
Animator animator = ViewAnimationUtils.createCircularReveal(
|
||||||
|
view, view.getWidth() / 2, view.getHeight() / 2, view.getWidth(), 0
|
||||||
|
);
|
||||||
|
animator.setInterpolator( new AccelerateDecelerateInterpolator() );
|
||||||
|
animator.setDuration( 2000 );
|
||||||
|
animator.start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectNumber() {
|
||||||
|
RG.setOnCheckedChangeListener( new RadioGroup.OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(RadioGroup group, int checkedId) {
|
||||||
|
switch (checkedId) {
|
||||||
|
case R.id.fourParts:
|
||||||
|
sp.PutData( context, "num", 4 );
|
||||||
|
break;
|
||||||
|
case R.id.sixParts:
|
||||||
|
sp.PutData( context, "num", 6 );
|
||||||
|
break;
|
||||||
|
case R.id.eightParts:
|
||||||
|
sp.PutData( context, "num", 8 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package franzliszt.foodturntable.animator;
|
||||||
|
|
||||||
|
public enum AnimationState {
|
||||||
|
|
||||||
|
MAIN_CIRCLE_TRANSLATED_TOP, MAIN_CIRCLE_SCALED_DISAPPEAR, MAIN_CIRCLE_FILLED_TOP,
|
||||||
|
MAIN_CIRCLE_DRAWN_TOP, MAIN_CIRCLE_TRANSLATED_CENTER, SECONDARY_CIRCLE_FINISHED,
|
||||||
|
SIDE_ARCS_RESIZED_TOP, FINISHED_OK, FINISHED_FAILURE, ANIMATION_END
|
||||||
|
}
|
@ -0,0 +1,195 @@
|
|||||||
|
package franzliszt.foodturntable.animator;
|
||||||
|
|
||||||
|
|
||||||
|
import com.franzliszt.foodturntable.AnimatedCircleLoadingView;
|
||||||
|
import com.franzliszt.foodturntable.component.ComponentViewAnimation;
|
||||||
|
import com.franzliszt.foodturntable.component.InitialCenterCircleView;
|
||||||
|
import com.franzliszt.foodturntable.component.MainCircleView;
|
||||||
|
import com.franzliszt.foodturntable.component.PercentIndicatorView;
|
||||||
|
import com.franzliszt.foodturntable.component.RightCircleView;
|
||||||
|
import com.franzliszt.foodturntable.component.SideArcsView;
|
||||||
|
import com.franzliszt.foodturntable.component.TopCircleBorderView;
|
||||||
|
import com.franzliszt.foodturntable.component.finish.FinishedFailureView;
|
||||||
|
import com.franzliszt.foodturntable.component.finish.FinishedOkView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jlmd
|
||||||
|
*/
|
||||||
|
public class ViewAnimator implements ComponentViewAnimation.StateListener {
|
||||||
|
|
||||||
|
private InitialCenterCircleView initialCenterCircleView;
|
||||||
|
private RightCircleView rightCircleView;
|
||||||
|
private SideArcsView sideArcsView;
|
||||||
|
private TopCircleBorderView topCircleBorderView;
|
||||||
|
private MainCircleView mainCircleView;
|
||||||
|
private FinishedOkView finishedOkView;
|
||||||
|
private FinishedFailureView finishedFailureView;
|
||||||
|
private PercentIndicatorView percentIndicatorView;
|
||||||
|
private AnimationState finishedState;
|
||||||
|
private boolean resetAnimator;
|
||||||
|
private AnimatedCircleLoadingView.AnimationListener animationListener;
|
||||||
|
|
||||||
|
public void setComponentViewAnimations(InitialCenterCircleView initialCenterCircleView,
|
||||||
|
RightCircleView rightCircleView, SideArcsView sideArcsView,
|
||||||
|
TopCircleBorderView topCircleBorderView, MainCircleView mainCircleView,
|
||||||
|
FinishedOkView finishedOkCircleView, FinishedFailureView finishedFailureView,
|
||||||
|
PercentIndicatorView percentIndicatorView) {
|
||||||
|
this.initialCenterCircleView = initialCenterCircleView;
|
||||||
|
this.rightCircleView = rightCircleView;
|
||||||
|
this.sideArcsView = sideArcsView;
|
||||||
|
this.topCircleBorderView = topCircleBorderView;
|
||||||
|
this.mainCircleView = mainCircleView;
|
||||||
|
this.finishedOkView = finishedOkCircleView;
|
||||||
|
this.finishedFailureView = finishedFailureView;
|
||||||
|
this.percentIndicatorView = percentIndicatorView;
|
||||||
|
initListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initListeners() {
|
||||||
|
initialCenterCircleView.setStateListener(this);
|
||||||
|
rightCircleView.setStateListener(this);
|
||||||
|
sideArcsView.setStateListener(this);
|
||||||
|
topCircleBorderView.setStateListener(this);
|
||||||
|
mainCircleView.setStateListener(this);
|
||||||
|
finishedOkView.setStateListener(this);
|
||||||
|
finishedFailureView.setStateListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startAnimator() {
|
||||||
|
finishedState = null;
|
||||||
|
initialCenterCircleView.showView();
|
||||||
|
initialCenterCircleView.startTranslateTopAnimation();
|
||||||
|
initialCenterCircleView.startScaleAnimation();
|
||||||
|
rightCircleView.showView();
|
||||||
|
rightCircleView.startSecondaryCircleAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetAnimator() {
|
||||||
|
initialCenterCircleView.hideView();
|
||||||
|
rightCircleView.hideView();
|
||||||
|
sideArcsView.hideView();
|
||||||
|
topCircleBorderView.hideView();
|
||||||
|
mainCircleView.hideView();
|
||||||
|
finishedOkView.hideView();
|
||||||
|
finishedFailureView.hideView();
|
||||||
|
resetAnimator = true;
|
||||||
|
startAnimator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finishOk() {
|
||||||
|
finishedState = AnimationState.FINISHED_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finishFailure() {
|
||||||
|
finishedState = AnimationState.FINISHED_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAnimationListener(AnimatedCircleLoadingView.AnimationListener animationListener) {
|
||||||
|
this.animationListener = animationListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStateChanged(AnimationState state) {
|
||||||
|
if (resetAnimator) {
|
||||||
|
resetAnimator = false;
|
||||||
|
} else {
|
||||||
|
switch (state) {
|
||||||
|
case MAIN_CIRCLE_TRANSLATED_TOP:
|
||||||
|
onMainCircleTranslatedTop();
|
||||||
|
break;
|
||||||
|
case MAIN_CIRCLE_SCALED_DISAPPEAR:
|
||||||
|
onMainCircleScaledDisappear();
|
||||||
|
break;
|
||||||
|
case MAIN_CIRCLE_FILLED_TOP:
|
||||||
|
onMainCircleFilledTop();
|
||||||
|
break;
|
||||||
|
case SIDE_ARCS_RESIZED_TOP:
|
||||||
|
onSideArcsResizedTop();
|
||||||
|
break;
|
||||||
|
case MAIN_CIRCLE_DRAWN_TOP:
|
||||||
|
onMainCircleDrawnTop();
|
||||||
|
break;
|
||||||
|
case FINISHED_OK:
|
||||||
|
onFinished(state);
|
||||||
|
break;
|
||||||
|
case FINISHED_FAILURE:
|
||||||
|
onFinished(state);
|
||||||
|
break;
|
||||||
|
case MAIN_CIRCLE_TRANSLATED_CENTER:
|
||||||
|
onMainCircleTranslatedCenter();
|
||||||
|
break;
|
||||||
|
case ANIMATION_END:
|
||||||
|
onAnimationEnd();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onMainCircleTranslatedTop() {
|
||||||
|
initialCenterCircleView.startTranslateBottomAnimation();
|
||||||
|
initialCenterCircleView.startScaleDisappear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onMainCircleScaledDisappear() {
|
||||||
|
initialCenterCircleView.hideView();
|
||||||
|
sideArcsView.showView();
|
||||||
|
sideArcsView.startRotateAnimation();
|
||||||
|
sideArcsView.startResizeDownAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onSideArcsResizedTop() {
|
||||||
|
topCircleBorderView.showView();
|
||||||
|
topCircleBorderView.startDrawCircleAnimation();
|
||||||
|
sideArcsView.hideView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onMainCircleDrawnTop() {
|
||||||
|
mainCircleView.showView();
|
||||||
|
mainCircleView.startFillCircleAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onMainCircleFilledTop() {
|
||||||
|
if (isAnimationFinished()) {
|
||||||
|
onStateChanged(finishedState);
|
||||||
|
percentIndicatorView.startAlphaAnimation();
|
||||||
|
} else {
|
||||||
|
topCircleBorderView.hideView();
|
||||||
|
mainCircleView.hideView();
|
||||||
|
initialCenterCircleView.showView();
|
||||||
|
initialCenterCircleView.startTranslateBottomAnimation();
|
||||||
|
initialCenterCircleView.startScaleDisappear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAnimationFinished() {
|
||||||
|
return finishedState != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onFinished(AnimationState state) {
|
||||||
|
topCircleBorderView.hideView();
|
||||||
|
mainCircleView.hideView();
|
||||||
|
finishedState = state;
|
||||||
|
initialCenterCircleView.showView();
|
||||||
|
initialCenterCircleView.startTranslateCenterAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onMainCircleTranslatedCenter() {
|
||||||
|
if (finishedState == AnimationState.FINISHED_OK) {
|
||||||
|
finishedOkView.showView();
|
||||||
|
finishedOkView.startScaleAnimation();
|
||||||
|
} else {
|
||||||
|
finishedFailureView.showView();
|
||||||
|
finishedFailureView.startScaleAnimation();
|
||||||
|
}
|
||||||
|
initialCenterCircleView.hideView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onAnimationEnd() {
|
||||||
|
if (animationListener != null) {
|
||||||
|
boolean success = finishedState == AnimationState.FINISHED_OK;
|
||||||
|
animationListener.onAnimationEnd(success);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package franzliszt.foodturntable.component;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.franzliszt.foodturntable.animator.AnimationState;
|
||||||
|
import com.franzliszt.foodturntable.exception.NullStateListenerException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jlmd
|
||||||
|
*/
|
||||||
|
public abstract class ComponentViewAnimation extends View {
|
||||||
|
|
||||||
|
protected final int parentWidth;
|
||||||
|
protected final int mainColor;
|
||||||
|
protected final int secondaryColor;
|
||||||
|
|
||||||
|
protected float parentCenter;
|
||||||
|
protected float circleRadius;
|
||||||
|
protected int strokeWidth;
|
||||||
|
private StateListener stateListener;
|
||||||
|
|
||||||
|
public ComponentViewAnimation(Context context, int parentWidth, int mainColor,
|
||||||
|
int secondaryColor) {
|
||||||
|
super(context);
|
||||||
|
this.parentWidth = parentWidth;
|
||||||
|
this.mainColor = mainColor;
|
||||||
|
this.secondaryColor = secondaryColor;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
hideView();
|
||||||
|
circleRadius = parentWidth / 10;
|
||||||
|
parentCenter = parentWidth / 2;
|
||||||
|
strokeWidth = (12 * parentWidth) / 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hideView() {
|
||||||
|
setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showView() {
|
||||||
|
setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(AnimationState state) {
|
||||||
|
if (stateListener != null) {
|
||||||
|
stateListener.onStateChanged(state);
|
||||||
|
} else {
|
||||||
|
throw new NullStateListenerException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStateListener(StateListener stateListener) {
|
||||||
|
this.stateListener = stateListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface StateListener {
|
||||||
|
|
||||||
|
void onStateChanged(AnimationState state);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,192 @@
|
|||||||
|
package franzliszt.foodturntable.component;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
import com.franzliszt.foodturntable.animator.AnimationState;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jlmd
|
||||||
|
*/
|
||||||
|
public class InitialCenterCircleView extends ComponentViewAnimation {
|
||||||
|
|
||||||
|
private Paint paint;
|
||||||
|
private RectF oval;
|
||||||
|
private float minRadius;
|
||||||
|
private float currentCircleWidth;
|
||||||
|
private float currentCircleHeight;
|
||||||
|
|
||||||
|
public InitialCenterCircleView(Context context, int parentWidth, int mainColor,
|
||||||
|
int secondaryColor) {
|
||||||
|
super(context, parentWidth, mainColor, secondaryColor);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
initOval();
|
||||||
|
initPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPaint() {
|
||||||
|
paint = new Paint();
|
||||||
|
paint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||||
|
paint.setColor(mainColor);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initOval() {
|
||||||
|
oval = new RectF();
|
||||||
|
minRadius = (15 * parentWidth) / 700;
|
||||||
|
currentCircleWidth = minRadius;
|
||||||
|
currentCircleHeight = minRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
drawCircle(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawCircle(Canvas canvas) {
|
||||||
|
|
||||||
|
RectF oval = new RectF();
|
||||||
|
oval.set(parentCenter - currentCircleWidth, parentCenter - currentCircleHeight,
|
||||||
|
parentCenter + currentCircleWidth, parentCenter + currentCircleHeight);
|
||||||
|
canvas.drawOval(oval, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startTranslateTopAnimation() {
|
||||||
|
float translationYTo = -(255 * parentWidth) / 700;
|
||||||
|
ObjectAnimator translationY = ObjectAnimator.ofFloat(this, "translationY", 0, translationYTo);
|
||||||
|
translationY.setDuration(1100);
|
||||||
|
translationY.addListener(new Animator.AnimatorListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
setState( AnimationState.MAIN_CIRCLE_TRANSLATED_TOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationRepeat(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
});
|
||||||
|
translationY.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startScaleAnimation() {
|
||||||
|
ValueAnimator valueAnimator = ValueAnimator.ofFloat(minRadius, circleRadius);
|
||||||
|
valueAnimator.setDuration(1400);
|
||||||
|
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
currentCircleWidth = (float) animation.getAnimatedValue();
|
||||||
|
currentCircleHeight = (float) animation.getAnimatedValue();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueAnimator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startTranslateBottomAnimation() {
|
||||||
|
float translationYFrom = -(260 * parentWidth) / 700;
|
||||||
|
float translationYTo = (360 * parentWidth) / 700;
|
||||||
|
ObjectAnimator translationY =
|
||||||
|
ObjectAnimator.ofFloat(this, "translationY", translationYFrom, translationYTo);
|
||||||
|
translationY.setDuration(650);
|
||||||
|
translationY.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startScaleDisappear() {
|
||||||
|
float maxScaleSize = (250 * parentWidth) / 700;
|
||||||
|
ValueAnimator valueScaleWidthAnimator = ValueAnimator.ofFloat(circleRadius, maxScaleSize);
|
||||||
|
valueScaleWidthAnimator.setDuration(260);
|
||||||
|
valueScaleWidthAnimator.setStartDelay(430);
|
||||||
|
valueScaleWidthAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
currentCircleWidth = (float) animation.getAnimatedValue();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueScaleWidthAnimator.addListener(new Animator.AnimatorListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
setState(AnimationState.MAIN_CIRCLE_SCALED_DISAPPEAR);
|
||||||
|
currentCircleWidth = circleRadius + (strokeWidth / 2);
|
||||||
|
currentCircleHeight = circleRadius + (strokeWidth / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationRepeat(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueScaleWidthAnimator.start();
|
||||||
|
|
||||||
|
ValueAnimator valueScaleHeightAnimator = ValueAnimator.ofFloat(circleRadius, circleRadius / 2);
|
||||||
|
valueScaleHeightAnimator.setDuration(260);
|
||||||
|
valueScaleHeightAnimator.setStartDelay(430);
|
||||||
|
valueScaleHeightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
currentCircleHeight = (float) animation.getAnimatedValue();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueScaleHeightAnimator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startTranslateCenterAnimation() {
|
||||||
|
float translationYFrom = -(260 * parentWidth) / 700;
|
||||||
|
ObjectAnimator translationY = ObjectAnimator.ofFloat(this, "translationY", translationYFrom, 0);
|
||||||
|
translationY.setDuration(650);
|
||||||
|
translationY.addListener(new Animator.AnimatorListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
setState(AnimationState.MAIN_CIRCLE_TRANSLATED_CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationRepeat(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
});
|
||||||
|
translationY.start();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package franzliszt.foodturntable.component;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
import franzliszt.foodturntable.animator.AnimationState;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jlmd
|
||||||
|
*/
|
||||||
|
public class MainCircleView extends ComponentViewAnimation {
|
||||||
|
|
||||||
|
private Paint paint;
|
||||||
|
private RectF oval;
|
||||||
|
private int arcFillAngle = 0;
|
||||||
|
private int arcStartAngle = 0;
|
||||||
|
|
||||||
|
public MainCircleView(Context context, int parentWidth, int mainColor, int secondaryColor) {
|
||||||
|
super(context, parentWidth, mainColor, secondaryColor);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
initPaint();
|
||||||
|
initOval();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPaint() {
|
||||||
|
paint = new Paint();
|
||||||
|
paint.setColor(mainColor);
|
||||||
|
paint.setStrokeWidth(strokeWidth);
|
||||||
|
paint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initOval() {
|
||||||
|
float padding = paint.getStrokeWidth() / 2;
|
||||||
|
oval = new RectF();
|
||||||
|
oval.set(parentCenter - circleRadius, padding, parentCenter + circleRadius, circleRadius * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
drawArcs(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawArcs(Canvas canvas) {
|
||||||
|
canvas.drawArc(oval, arcStartAngle, arcFillAngle, false, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startFillCircleAnimation() {
|
||||||
|
ValueAnimator valueAnimator = ValueAnimator.ofInt(90, 360);
|
||||||
|
valueAnimator.setDuration(800);
|
||||||
|
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
arcStartAngle = (int) animation.getAnimatedValue();
|
||||||
|
arcFillAngle = (90 - arcStartAngle) * 2;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueAnimator.addListener(new Animator.AnimatorListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
setState( AnimationState.MAIN_CIRCLE_FILLED_TOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationRepeat(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueAnimator.start();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package franzliszt.foodturntable.component;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.animation.AlphaAnimation;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jlmd
|
||||||
|
*/
|
||||||
|
public class PercentIndicatorView extends TextView {
|
||||||
|
|
||||||
|
private final int parentWidth;
|
||||||
|
private int textColor = Color.WHITE;
|
||||||
|
|
||||||
|
public PercentIndicatorView(Context context, int parentWidth, int textColor) {
|
||||||
|
super(context);
|
||||||
|
this.parentWidth = parentWidth;
|
||||||
|
this.textColor = textColor;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
int textSize = (35 * parentWidth) / 700;
|
||||||
|
setTextSize(textSize);
|
||||||
|
setTextColor(this.textColor);
|
||||||
|
setGravity(Gravity.CENTER);
|
||||||
|
setAlpha(0.8f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPercent(int percent) {
|
||||||
|
setText(percent + "%");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startAlphaAnimation() {
|
||||||
|
AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
|
||||||
|
alphaAnimation.setDuration(700);
|
||||||
|
alphaAnimation.setFillAfter(true);
|
||||||
|
startAnimation(alphaAnimation);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
package franzliszt.foodturntable.component;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.view.animation.AlphaAnimation;
|
||||||
|
import android.view.animation.Animation;
|
||||||
|
import android.view.animation.AnimationSet;
|
||||||
|
import android.view.animation.TranslateAnimation;
|
||||||
|
|
||||||
|
import com.franzliszt.foodturntable.animator.AnimationState;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jlmd
|
||||||
|
*/
|
||||||
|
public class RightCircleView extends ComponentViewAnimation {
|
||||||
|
|
||||||
|
private int rightMargin;
|
||||||
|
private int bottomMargin;
|
||||||
|
private Paint paint;
|
||||||
|
|
||||||
|
public RightCircleView(Context context, int parentWidth, int mainColor, int secondaryColor) {
|
||||||
|
super(context, parentWidth, mainColor, secondaryColor);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
rightMargin = (150 * parentWidth / 700);
|
||||||
|
bottomMargin = (50 * parentWidth / 700);
|
||||||
|
initPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPaint() {
|
||||||
|
paint = new Paint();
|
||||||
|
paint.setStyle(Paint.Style.FILL);
|
||||||
|
paint.setColor(secondaryColor);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
drawCircle(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawCircle(Canvas canvas) {
|
||||||
|
canvas.drawCircle(getWidth() - rightMargin, parentCenter - bottomMargin, circleRadius, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startSecondaryCircleAnimation() {
|
||||||
|
int bottomMovementAddition = (260 * parentWidth) / 700;
|
||||||
|
TranslateAnimation translateAnimation =
|
||||||
|
new TranslateAnimation(getX(), getX(), getY(), getY() + bottomMovementAddition);
|
||||||
|
translateAnimation.setStartOffset(200);
|
||||||
|
translateAnimation.setDuration(1000);
|
||||||
|
|
||||||
|
AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
|
||||||
|
alphaAnimation.setStartOffset(1300);
|
||||||
|
alphaAnimation.setDuration(200);
|
||||||
|
|
||||||
|
AnimationSet animationSet = new AnimationSet(true);
|
||||||
|
animationSet.addAnimation(translateAnimation);
|
||||||
|
animationSet.addAnimation(alphaAnimation);
|
||||||
|
animationSet.setFillAfter(true);
|
||||||
|
animationSet.setAnimationListener(new Animation.AnimationListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animation animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animation animation) {
|
||||||
|
setState( AnimationState.SECONDARY_CIRCLE_FINISHED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationRepeat(Animation animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
startAnimation(animationSet);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
package franzliszt.foodturntable.component;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
|
||||||
|
import com.franzliszt.foodturntable.animator.AnimationState;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jlmd
|
||||||
|
*/
|
||||||
|
public class SideArcsView extends ComponentViewAnimation {
|
||||||
|
|
||||||
|
private static final int MIN_RESIZE_ANGLE = 8;
|
||||||
|
private static final int MAX_RESIZE_ANGLE = 45;
|
||||||
|
private static final int INITIAL_LEFT_ARC_START_ANGLE = 100;
|
||||||
|
private static final int INITIAL_RIGHT_ARC_START_ANGLE = 80;
|
||||||
|
private static final int MIN_START_ANGLE = 0;
|
||||||
|
private static final int MAX_START_ANGLE = 165;
|
||||||
|
private int startLeftArcAngle = INITIAL_LEFT_ARC_START_ANGLE;
|
||||||
|
private int startRightArcAngle = INITIAL_RIGHT_ARC_START_ANGLE;
|
||||||
|
private Paint paint;
|
||||||
|
private RectF oval;
|
||||||
|
private int arcAngle;
|
||||||
|
|
||||||
|
public SideArcsView(Context context, int parentWidth, int mainColor, int secondaryColor) {
|
||||||
|
super(context, parentWidth, mainColor, secondaryColor);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
initPaint();
|
||||||
|
arcAngle = MAX_RESIZE_ANGLE;
|
||||||
|
initOval();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPaint() {
|
||||||
|
paint = new Paint();
|
||||||
|
paint.setColor(mainColor);
|
||||||
|
paint.setStrokeWidth(strokeWidth);
|
||||||
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initOval() {
|
||||||
|
float padding = paint.getStrokeWidth() / 2;
|
||||||
|
oval = new RectF();
|
||||||
|
oval.set(padding, padding, parentWidth - padding, parentWidth - padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
drawArcs(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawArcs(Canvas canvas) {
|
||||||
|
canvas.drawArc(oval, startLeftArcAngle, arcAngle, false, paint);
|
||||||
|
canvas.drawArc(oval, startRightArcAngle, -arcAngle, false, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startRotateAnimation() {
|
||||||
|
ValueAnimator valueAnimator = ValueAnimator.ofInt(MIN_START_ANGLE, MAX_START_ANGLE);
|
||||||
|
valueAnimator.setInterpolator(new DecelerateInterpolator());
|
||||||
|
valueAnimator.setDuration(550);
|
||||||
|
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
startLeftArcAngle = INITIAL_LEFT_ARC_START_ANGLE + (int) animation.getAnimatedValue();
|
||||||
|
startRightArcAngle = INITIAL_RIGHT_ARC_START_ANGLE - ((int) animation.getAnimatedValue());
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueAnimator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startResizeDownAnimation() {
|
||||||
|
ValueAnimator valueAnimator = ValueAnimator.ofInt(MAX_RESIZE_ANGLE, MIN_RESIZE_ANGLE);
|
||||||
|
valueAnimator.setInterpolator(new DecelerateInterpolator());
|
||||||
|
valueAnimator.setDuration(620);
|
||||||
|
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
arcAngle = (int) animation.getAnimatedValue();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueAnimator.addListener(new Animator.AnimatorListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
setState( AnimationState.SIDE_ARCS_RESIZED_TOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationRepeat(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueAnimator.start();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,95 @@
|
|||||||
|
package franzliszt.foodturntable.component;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
|
||||||
|
import com.franzliszt.foodturntable.animator.AnimationState;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jlmd
|
||||||
|
*/
|
||||||
|
public class TopCircleBorderView extends ComponentViewAnimation {
|
||||||
|
|
||||||
|
private static final int MIN_ANGLE = 25;
|
||||||
|
private static final int MAX_ANGLE = 180;
|
||||||
|
private Paint paint;
|
||||||
|
private RectF oval;
|
||||||
|
private int arcAngle;
|
||||||
|
|
||||||
|
public TopCircleBorderView(Context context, int parentWidth, int mainColor, int secondaryColor) {
|
||||||
|
super(context, parentWidth, mainColor, secondaryColor);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
initPaint();
|
||||||
|
initOval();
|
||||||
|
arcAngle = MIN_ANGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPaint() {
|
||||||
|
paint = new Paint();
|
||||||
|
paint.setColor(mainColor);
|
||||||
|
paint.setStrokeWidth(strokeWidth);
|
||||||
|
paint.setStyle(Paint.Style.STROKE);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initOval() {
|
||||||
|
float padding = paint.getStrokeWidth() / 2;
|
||||||
|
oval = new RectF();
|
||||||
|
oval.set(parentCenter - circleRadius, padding, parentCenter + circleRadius, circleRadius * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
drawArcs(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawArcs(Canvas canvas) {
|
||||||
|
canvas.drawArc(oval, 270, arcAngle, false, paint);
|
||||||
|
canvas.drawArc(oval, 270, -arcAngle, false, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startDrawCircleAnimation() {
|
||||||
|
ValueAnimator valueAnimator = ValueAnimator.ofInt(MIN_ANGLE, MAX_ANGLE);
|
||||||
|
valueAnimator.setInterpolator(new DecelerateInterpolator());
|
||||||
|
valueAnimator.setDuration(400);
|
||||||
|
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
arcAngle = (int) animation.getAnimatedValue();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueAnimator.addListener(new Animator.AnimatorListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
setState( AnimationState.MAIN_CIRCLE_DRAWN_TOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationRepeat(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueAnimator.start();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package franzliszt.foodturntable.component.finish;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import franzliszt.foodturntable.R;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jlmd
|
||||||
|
*/
|
||||||
|
public class FinishedFailureView extends FinishedView {
|
||||||
|
|
||||||
|
public FinishedFailureView(Context context, int parentWidth, int mainColor, int secondaryColor,
|
||||||
|
int tintColor) {
|
||||||
|
super(context, parentWidth, mainColor, secondaryColor, tintColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getDrawable() {
|
||||||
|
return R.drawable.ic_failure_mark;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getDrawableTintColor() {
|
||||||
|
return tintColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getCircleColor() {
|
||||||
|
return secondaryColor;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package franzliszt.foodturntable.component.finish;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.franzliszt.foodturntable.R;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jlmd
|
||||||
|
*/
|
||||||
|
public class FinishedOkView extends FinishedView {
|
||||||
|
|
||||||
|
public FinishedOkView(Context context, int parentWidth, int mainColor, int secondaryColor,
|
||||||
|
int tintColor) {
|
||||||
|
super(context, parentWidth, mainColor, secondaryColor, tintColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getDrawable() {
|
||||||
|
return R.drawable.ic_checked_mark;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getDrawableTintColor() {
|
||||||
|
return tintColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getCircleColor() {
|
||||||
|
return mainColor;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,128 @@
|
|||||||
|
package franzliszt.foodturntable.component.finish;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.LightingColorFilter;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
|
||||||
|
import com.franzliszt.foodturntable.animator.AnimationState;
|
||||||
|
import com.franzliszt.foodturntable.component.ComponentViewAnimation;
|
||||||
|
|
||||||
|
import franzliszt.foodturntable.component.ComponentViewAnimation;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jlmd
|
||||||
|
*/
|
||||||
|
public abstract class FinishedView extends ComponentViewAnimation {
|
||||||
|
|
||||||
|
private static final int MIN_IMAGE_SIZE = 1;
|
||||||
|
protected final int tintColor;
|
||||||
|
private int maxImageSize;
|
||||||
|
private int circleMaxRadius;
|
||||||
|
private Bitmap originalFinishedBitmap;
|
||||||
|
private float currentCircleRadius;
|
||||||
|
private int imageSize;
|
||||||
|
|
||||||
|
public FinishedView(Context context, int parentWidth, int mainColor, int secondaryColor,
|
||||||
|
int tintColor) {
|
||||||
|
super(context, parentWidth, mainColor, secondaryColor);
|
||||||
|
this.tintColor = tintColor;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
maxImageSize = (140 * parentWidth) / 700;
|
||||||
|
circleMaxRadius = (140 * parentWidth) / 700;
|
||||||
|
currentCircleRadius = circleRadius;
|
||||||
|
imageSize = MIN_IMAGE_SIZE;
|
||||||
|
originalFinishedBitmap = BitmapFactory.decodeResource(getResources(), getDrawable());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
drawCircle(canvas);
|
||||||
|
drawCheckedMark(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawCheckedMark(Canvas canvas) {
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setColorFilter(new LightingColorFilter(getDrawableTintColor(), 0));
|
||||||
|
|
||||||
|
Bitmap bitmap = Bitmap.createScaledBitmap(originalFinishedBitmap, imageSize, imageSize, true);
|
||||||
|
canvas.drawBitmap(bitmap, parentCenter - bitmap.getWidth() / 2,
|
||||||
|
parentCenter - bitmap.getHeight() / 2, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawCircle(Canvas canvas) {
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||||
|
paint.setColor(getCircleColor());
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
canvas.drawCircle(parentCenter, parentCenter, currentCircleRadius, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startScaleAnimation() {
|
||||||
|
startScaleCircleAnimation();
|
||||||
|
startScaleImageAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startScaleCircleAnimation() {
|
||||||
|
ValueAnimator valueCircleAnimator =
|
||||||
|
ValueAnimator.ofFloat(circleRadius + strokeWidth / 2, circleMaxRadius);
|
||||||
|
valueCircleAnimator.setDuration(1000);
|
||||||
|
valueCircleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
currentCircleRadius = (float) animation.getAnimatedValue();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueCircleAnimator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startScaleImageAnimation() {
|
||||||
|
ValueAnimator valueImageAnimator = ValueAnimator.ofInt(MIN_IMAGE_SIZE, maxImageSize);
|
||||||
|
valueImageAnimator.setDuration(1000);
|
||||||
|
valueImageAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
imageSize = (int) animation.getAnimatedValue();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueImageAnimator.addListener(new Animator.AnimatorListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
setState( AnimationState.ANIMATION_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationRepeat(Animator animation) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
});
|
||||||
|
valueImageAnimator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract int getDrawable();
|
||||||
|
|
||||||
|
protected abstract int getDrawableTintColor();
|
||||||
|
|
||||||
|
protected abstract int getCircleColor();
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue