Branch_QYJ
李雨轩 3 years ago
parent 3f35a227f0
commit d6000bd5ce

Binary file not shown.

@ -10,12 +10,12 @@ android {
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
/* buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}*/
}
dependencies {

@ -37,7 +37,7 @@
<!-- 定义了使用ToolBar控件的布局的标题为food -->
<activity
android:name=".Activity.OrderActivity"
android:label="潮汕牛肉"></activity>
android:label="航吃Hang吃"></activity>
<activity
android:name=".Activity.FoodActivity"
android:theme="@style/foodActivityTheme"></activity>
@ -50,6 +50,7 @@
<activity android:name=".Activity.ReadOrderActivity" />
<activity android:name=".Activity.MyMoneyActivity" />
<activity android:name=".Activity.SettingActivity" />
<activity android:name=".Activity.horizonta_main"/>
</application>
</manifest>

@ -0,0 +1,199 @@
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.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ProgressBar;
import com.sbw.atrue.Order.R;
/**
* Created by user on 2017-8-8.
*
* ProgressBar
*/
public class CustomHorizontalProgres extends ProgressBar{
//默认值
private static final int DEAFUALT_PROGRESS_UNREACH_HEIGHH = 10;//dp
private static final int DEAFUALT_PROGRESS_UNREACH_CORLOR = 0xFFD3D6DA;
private static final int DEAFUALT_PROGRESS_REACH_HEIGHH = 10;//dp
private static final int DEAFUALT_PROGRESS_REACH_CORLOR = 0xFFFC00D1;
private static final int DEAFUALT_PROGRESS_TEXT_SIZE = 10;//sp
private static final int DEAFUALT_PROGRESS_TEXT_CORLOR = 0xFFD3D6DA;
private static final int DEAFUALT_PROGRESS_TEXT_OFFSET = 10;//dp
private static final int DEAFUALT_PROGRESS_VIEW_WIDTH = 200;//进度条默认宽度
private int HorizontalProgresUnReachColor;//不能用static修饰,不然多个View会共用此属性
private int HorizontalProgresUnReachHeight;
private int HorizontalProgresReachColor;
private int HorizontalProgresReachHeight;
private int HorizontalProgresTextColor;
private int HorizontalProgresTextSize;
private int HorizontalProgresTextOffset;
private Paint mPaint = new Paint();
public CustomHorizontalProgres(Context context) {
this(context,null);
}
public CustomHorizontalProgres(Context context, AttributeSet attrs) {
this(context,attrs,0);
}
public CustomHorizontalProgres(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
geStyleabletAttr(attrs);
mPaint.setTextSize(HorizontalProgresTextSize);//设置画笔文字大小,便于后面测量文字宽高
mPaint.setColor(HorizontalProgresTextColor);
}
/**
*
*/
private void geStyleabletAttr(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();//记得加这句
/*TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.);
int textColor = a.getColor(R.styleable._, );
https://www.jianshu.com/p/8d388894d9e9*/
}
@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(getPaddingLeft()+progressX + HorizontalProgresTextOffset + textWidth,getPaddingTop()-HorizontalProgresUnReachHeight/2,getWidth() - getPaddingLeft() - getPaddingRight(),HorizontalProgresUnReachHeight/2);//圆角 int left, int top, int right, int bottom
canvas.drawRoundRect(mRectF2,15,15,mPaint);//圆角矩形
}
canvas.restore();
}
/**
* dppx
*
* @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());
}
/**
* sppx
*
* @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
*/
private 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
*/
private 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,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();
}
/**
* dppx
*
* @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());
}
/**
* sppx
*
* @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();
}
/**
* dppx
*
* @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());
}
/**
* sppx
*
* @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;
}
}

@ -17,8 +17,6 @@ import com.sbw.atrue.Order.R;
/**
* ClassName: FoodActivity <br>
* description: <br>
* author: -13042299081 <br>
* Date: 2019/2/18 20:59
*/
public class FoodActivity extends AppCompatActivity {

@ -59,30 +59,36 @@ public class InputActivity extends Activity {
final String address = ettable.getText().toString(); //获取输入框中的桌号
final String name = etname.getText().toString(); //获取输入框中的客户姓名
final String phone = etPhone.getText().toString(); //获取输入框中的手机号
if (!TextUtils.isEmpty(phone)
Intent intent = new Intent(getApplicationContext(), SuccessActivity.class); //新建意图
startActivity(intent); //跳转到购买成功页面
// ShoppingActivity.mInstance.finish(); //结束购物界面
// InputActivity.this.finish(); //结束信息输入界面
/* if (!TextUtils.isEmpty(phone)
&& !TextUtils.isEmpty(address)
&& phone.length() >= 7) { //手机号和地址不为空且手机号大于等于7位
addOrder(selectedProducts, name, phone, address, new MyListener<String>() {
*//* addOrder(selectedProducts, name, phone, address, new MyListener<String>() {
@Override
public void onSuccess(String data) {
Intent intent = new Intent(getApplicationContext(), SuccessActivity.class); //新建意图
intent.putParcelableArrayListExtra("selectedProducts", selectedProducts); //给意图添加被选择的的商品数据
intent.putExtra("name", name); //给意图设置客户姓名
// intent.putParcelableArrayListExtra("selectedProducts", selectedProducts); //给意图添加被选择的的商品数据
*//**//*intent.putExtra("name", name); //给意图设置客户姓名
intent.putExtra("phone", phone); //给意图设置联系电话
intent.putExtra("orderId", data); //给意图设置用餐桌号
intent.putExtra("table", address); //给意图设置用餐桌号
intent.putExtra("table", address); //给意图设置用餐桌号*//**//*
startActivity(intent); //跳转到购买成功页面
ShoppingActivity.mInstance.finish(); //结束购物界面
InputActivity.this.finish(); //结束信息输入界面
}
});
});*//*
} else { //输入手机号或地址不正确
//Toast.makeText(InputActivity.this, "手机号或地址输入不正确手机号至少7位", Toast.LENGTH_SHORT).show();
showDialog("手机号或地址输入不正确手机号至少7位!");
}
}*/
}
});
}
@ -109,7 +115,7 @@ public class InputActivity extends Activity {
@Override
public void onSucceed(int what, Response<JSONObject> response) {
JSONObject res = response.get();
/* JSONObject res = response.get();
try {
if (res.getInt("status") == 0) {
literer.onSuccess(res.getString("data"));
@ -118,11 +124,12 @@ public class InputActivity extends Activity {
}
} catch (JSONException e) {
e.printStackTrace();
}
}*/
}
@Override
public void onFailed(int what, Response<JSONObject> response) {
}
@Override

@ -30,8 +30,6 @@ import java.util.Map;
/**
* ClassName: LoginActivity <br>
* description: <br>
* author: -13042299081 <br>
* Date: 2019/2/18 14:54
*/
public class LoginActivity extends AppCompatActivity {
private EditText accountEdit;
@ -167,3 +165,5 @@ public class LoginActivity extends AppCompatActivity {
alert.show();
}
}

@ -1,8 +1,11 @@
package com.sbw.atrue.Order.Activity;
import android.view.View;
import com.yanzhenjie.nohttp.InitializationConfig;
import com.yanzhenjie.nohttp.NoHttp;
import org.litepal.LitePalApplication;
import org.litepal.tablemanager.Connector;
import org.litepal.util.Const;
public class MyApplication extends LitePalApplication {
@ -10,12 +13,14 @@ public class MyApplication extends LitePalApplication {
public void onCreate() {//可理解为我们之前的主函数
super.onCreate();
Connection.mymysql();
InitializationConfig config = InitializationConfig.newBuilder(this)
.connectionTimeout(30 * 1000)
.readTimeout(30 * 1000)
.retry(10)
.build();
NoHttp.initialize(config);
}
}
/*public class MyApplication extends Application {

@ -23,8 +23,6 @@ import org.json.JSONObject;
/**
* FileName: MyMoneyActivity <br>
* Description: <br>
* Author: -13042299081 <br>
* Date: 2019/4/12 16:51
*/
public class MyMoneyActivity extends Activity {
//账户余额显示文字控件

@ -1,5 +1,37 @@
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 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);
// }
}

@ -58,8 +58,6 @@ import java.util.List;
/**
* ClassName: OrderActivity <br>
* description: <br>
* author: -13042299081 <br>
* Date: 2019/2/18 21:03
*/
public class OrderActivity extends AppCompatActivity {
//从生产类中加载系统存储的菜单列表
@ -283,8 +281,11 @@ public class OrderActivity extends AppCompatActivity {
public void run() {
//向菜单中增加新菜
if (first == 0) {
Food WanZi = new Food("牛肉丸", "R.drawable.wanzi", "牛肉丸是潮汕美食啊!!!");
Food WanZi = new Food("牛肉汤", "R.drawable.wanzi", "南三 牛肉汤\n牛肉是山西平遥特产");
foodList.add(WanZi);
/* first = 1;*/
Food bingzi = new Food("大饼", "R.drawable.bingzi", "北一一楼 大饼卷万物\n很多选择快来");
foodList.add(bingzi);
first = 1;
}
//通知适配器数据发生了变化用于RecycleView自动更新显示项

@ -23,8 +23,6 @@ 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; //姓名输入框

@ -100,6 +100,9 @@ public class ShoppingActivity extends Activity {
@Override
public void onFailed(int what, Response<JSONObject> response) {
Product product = new Product(1,"牛肉汤", 10.5, "R.drawable.noodle", 100, "淮南牛肉汤", "美味牛肉汤!快来品尝", true);
productsData.add(product);
productListAdapter.notifyDataSetChanged();
}
@Override
@ -137,8 +140,9 @@ public class ShoppingActivity extends Activity {
@Override
public void onClick(View v) {
if (selectedProducts.size() != 0) { //已选择商品数据不为空
Intent intent = new Intent(getApplicationContext(), InputActivity.class); //新建意图
intent.putParcelableArrayListExtra("selectedProducts", selectedProducts); //设置已选择的商品数据
// Intent intent = new Intent(getApplicationContext(), InputActivity.class); //新建意图
Intent intent = new Intent(getApplicationContext(), horizonta_main.class); //新建意图
// intent.putParcelableArrayListExtra("selectedProducts", selectedProducts); //设置已选择的商品数据
startActivity(intent); //启动信息输入界面
} else { //已选择商品数据为空
showDialog("购物车为空,请选择商品!");

@ -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);
}
}

@ -5,8 +5,6 @@ import java.io.Serializable;
/**
* ClassName: Food <br >
* description: Intent <br>
* author: -13042299081 <br>
* Date: 2019/2/18 22:08
*/
public class Food implements Serializable {
//菜品名称

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#82b2ff" />
<solid android:color="#BBAE99" />
<corners android:radius="25dp" />
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 KiB

Binary file not shown.

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>

@ -12,7 +12,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:text="订单确认"
android:text="信息确认"
android:textSize="24sp" />
<LinearLayout
@ -34,7 +34,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="text"
android:text="沈滨伟" />
android:text="student" />
</LinearLayout>
<LinearLayout
@ -57,7 +57,7 @@
android:layout_weight="1"
android:ems="10"
android:inputType="phone"
android:text="13042299081" />
android:text="1234561" />
</LinearLayout>
<LinearLayout
@ -71,7 +71,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="您的桌号" />
android:text="您的身体情况" />
<EditText
android:id="@+id/et_table"

@ -4,20 +4,23 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/welcome">
android:background="@drawable/ninglibrary">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_marginTop="200dp"
android:layout_marginBottom="20dp"
android:layout_height="60dp">
<TextView
android:layout_width="123dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?attr/colorBackgroundFloating"
android:gravity="center_horizontal"
android:text="Account:"
android:text="账 号:"
android:textColor="#000000"
android:textSize="24sp" />
<EditText
@ -26,7 +29,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:hint="请输入账户" />
android:hint="请输入账户"
android:textColorHint="#000000"/>
</LinearLayout>
<LinearLayout
@ -38,9 +42,10 @@
android:layout_width="125dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?attr/colorBackgroundFloating"
android:gravity="center_horizontal"
android:text="Password:"
android:text="密 码:"
android:textColor="#000000"
android:textSize="24sp" />
<EditText
@ -50,7 +55,8 @@
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:inputType="textPassword"
android:hint="请输入密码"/>
android:hint="请输入密码"
android:textColorHint="#000000"/>
</LinearLayout>
<Button
@ -65,17 +71,18 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="100dp"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="@+id/register"
android:layout_width="wrap_content"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:text="注册"
android:textSize="20sp"
tools:background="@android:color/background_light" />
android:textSize="24sp"
tools:background="@drawable/btn_bg" />
</LinearLayout>

@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/welcome"
android:background="@drawable/ninglibrary"
android:orientation="vertical"
android:padding="10dp"
tools:context="com.sbw.atrue.Order.Activity.RegisterActivity">
@ -12,9 +12,11 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=" 注册页"
android:textColor="@color/colorAccent"
android:textSize="30sp" />
android:text="注册"
android:textColor="#ffffff"
android:textSize="30sp"
android:gravity="center"
android:layout_marginTop="20dp"/>
<EditText
@ -98,15 +100,16 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/background_light"
android:text="已有帐号?请"
android:text="已有帐号?请 "
android:textColor="@color/design_default_color_on_secondary"
android:textSize="16sp" />
<Button

@ -135,6 +135,6 @@
android:layout_weight="1"
android:textColor="#fff9f9"
android:background="@color/colorAccent"
android:text="下单" />
android:text="健康信息展示" />
</LinearLayout>
</LinearLayout>

@ -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>
<string name="app_name">潮汕牛肉</string>
<string name="app_name">航吃Hang吃</string>
<string name="随即转盘">吃货大赏</string>
</resources>

@ -4,5 +4,5 @@
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Fri Oct 21 20:41:36 GMT+08:00 2022
sdk.dir=D\:\\Android\\Sdk
#Mon Oct 31 23:18:23 CST 2022
sdk.dir=D\:\\Android SDK

@ -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>

@ -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,17 @@
### 简介
- 2018年天津市大学生创新训练项目—“基于Android的无线点餐系统的设计与研究”。本课题旨在研究并设计一基于Android的无线点餐系统系统能实现顾客就餐全过程的自动化管理。
- 对于系统功能设计:主要包括功能框架和设计模块,其中功能框架主要包括登录模块、点餐模块、结账模块和餐台管理;功能模块设计分为服务器和客户端,具体包括登录功能、用户管理、菜谱管理、系统管理。各模块之间互相依赖,形成一个完整的无线点餐系统手机(平板)客户端与服务器的交互设计系统。
### 研究内容
- A、确立物理架构Android系统客户端通过无线网络访问后台Web服务器如果需要数据访问则访问后台数据库服务器
- B、确立技术选型Android客户端选用JAVA技术网络通信选用Apache Http协议而中间Web服务器采用Servlet响应可客户请求。后台数据库使用JDBC来访问数据库Android客户端部分数据的存储则采用SQLite数据库
- C、进行系统规划和需求分析通过数据流程图、实体属性图分析数据间的关系设计并创建一个合理可靠的数据库
- D、实现客户端功能设计基于Android开发平台前端客户端功能模块大概分为锁定桌号、桌号查询、菜品查询、加菜功能、退菜功能、结算功能
- E、实现服务器端功能设计后端服务器功能模块大概分为用户评价管理、桌号管理、菜品管理、订单管理、信息管理
- F、后端服务器采用Tomcat服务器利用JDBC访问后台数据库Servlet响应HttpRequest请求并返回响应结果在此过程中采用MVC+DAO的设计模式及分层的开发思想。
### 系统页面
![输入图片说明](https://images.gitee.com/uploads/images/2019/0516/160858_7c04667b_2108662.png "2.png")

@ -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')
}

@ -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

@ -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,68 @@
package com.sbw.atrue.Order.Activity;
import android.content.Intent;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.sbw.atrue.Order.Entity.Food;
import com.sbw.atrue.Order.R;
/**
* ClassName: FoodActivity <br>
* description: <br>
* author: -13042299081 <br>
* Date: 2019/2/18 20:59
*/
public class FoodActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_food);
//获取各布局控件的实例
CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
ImageView foodImageView = (ImageView) findViewById(R.id.food_image_view);
TextView foodContentText = (TextView) findViewById(R.id.food_content_text);
//从上一级活动获取用户点击的菜品的对象
Intent intent = getIntent();
Food food=(Food)intent.getSerializableExtra("Food_Choose");
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
//显示标题栏最左侧的系统默认自带的返回导航键,用于返回上一级活动
actionBar.setDisplayHomeAsUpEnabled(true);
}
//设置菜品的名称、图片
collapsingToolbar.setTitle(food.getName());
Glide.with(this).load(food.getImageId()).into(foodImageView);
//设置菜品详情介绍
foodContentText.setText(food.getDescription());
}
/**
*
* @param item
* @return
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
//R.id.home是系统默认的ActionBar标题栏最左侧按键HomeAsUp键的Id
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}

@ -0,0 +1,160 @@
package com.sbw.atrue.Order.Activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
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.Toast;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.sbw.atrue.Order.R;
import com.sbw.atrue.Order.Entity.Product;
import com.sbw.atrue.Order.Util.HttpUtil;
import com.sbw.atrue.Order.Util.MyListener;
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 InputActivity extends Activity {
private EditText etname; //姓名输入框
private EditText etPhone; //手机号输入框
private EditText ettable; //桌号输入框
private Button btnInputCompleted; //输入完成按钮
private ArrayList<Product> selectedProducts = new ArrayList<Product>(); //被选择的的商品数据
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_input);
initViews(); //初始化页面控件
initEvents(); //初始化控件事件
}
//初始化控件事件
private void initEvents() {
Intent otherIntent = getIntent(); //获取信息输入界面传来的意图
selectedProducts = otherIntent.getParcelableArrayListExtra("selectedProducts"); //从意图中获取被选择的的商品数据
etPhone.setSelection(etPhone.getText().length()); //将光标移动到电话输入框最后面
etname.setText(ShareUtils.getString(InputActivity.this, "user_true_name", ""));//从本地读取客户姓名
etPhone.setText(ShareUtils.getString(InputActivity.this, "user_true_phone", ""));//从本地读取客户电话
//给输入完成按钮设置点击事件
btnInputCompleted.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final String address = ettable.getText().toString(); //获取输入框中的桌号
final String name = etname.getText().toString(); //获取输入框中的客户姓名
final String phone = etPhone.getText().toString(); //获取输入框中的手机号
if (!TextUtils.isEmpty(phone)
&& !TextUtils.isEmpty(address)
&& phone.length() >= 7) { //手机号和地址不为空且手机号大于等于7位
addOrder(selectedProducts, name, phone, address, new MyListener<String>() {
@Override
public void onSuccess(String data) {
Intent intent = new Intent(getApplicationContext(), SuccessActivity.class); //新建意图
intent.putParcelableArrayListExtra("selectedProducts", selectedProducts); //给意图添加被选择的的商品数据
intent.putExtra("name", name); //给意图设置客户姓名
intent.putExtra("phone", phone); //给意图设置联系电话
intent.putExtra("orderId", data); //给意图设置用餐桌号
intent.putExtra("table", address); //给意图设置用餐桌号
startActivity(intent); //跳转到购买成功页面
ShoppingActivity.mInstance.finish(); //结束购物界面
InputActivity.this.finish(); //结束信息输入界面
}
});
} else { //输入手机号或地址不正确
//Toast.makeText(InputActivity.this, "手机号或地址输入不正确手机号至少7位", Toast.LENGTH_SHORT).show();
showDialog("手机号或地址输入不正确手机号至少7位!");
}
}
});
}
private void addOrder(List<Product> productList, String name, String phone, String address, final MyListener<String> literer) {
String postUrl = HttpUtil.HOST + "api/order/addOrder";
//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));
request.add("name", name);
request.add("phone", phone);
request.add("tableId", address);
request.add("productList", new Gson().toJson(productList));
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) {
literer.onSuccess(res.getString("data"));
} else {
showDialog(res.getString("msg"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailed(int what, Response<JSONObject> response) {
}
@Override
public void onFinish(int what) {
}
});
}
//初始化页面控件
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);
}
/**
* 便
*
* @param msg
*/
private void showDialog(String msg) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(msg)
.setCancelable(false)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
}
}

@ -0,0 +1,164 @@
package com.sbw.atrue.Order.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.text.TextUtils;
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;
import java.util.Map;
/**
* ClassName: LoginActivity <br>
* description: <br>
* author: -13042299081 <br>
* Date: 2019/2/18 14:54
*/
public class LoginActivity extends AppCompatActivity {
private EditText accountEdit;
private EditText passwordEdit;
private Button btnlogin;
private Button btnRegister;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initViews(); //初始化页面控件
initEvents(); //初始化控件事件
}
//初始化页面控件
private void initViews() {
accountEdit = (EditText) findViewById(R.id.account);
passwordEdit = (EditText) findViewById(R.id.password);
btnlogin = (Button) findViewById(R.id.login);
btnRegister = (Button) findViewById(R.id.register);
}
//初始化控件事件
private void initEvents() {
//给登录按钮设置点击事件
btnlogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String account = accountEdit.getText().toString();
String password = passwordEdit.getText().toString();
//判断用户名和密码是否正确
if (!TextUtils.isEmpty(account) && !TextUtils.isEmpty(password)) { //用户名和密码都不为空
//尝试登陆
tryToLogin(account, password);
} else {
showDialog("用户名或密码不能为空!");
}
}
});
//给注册按钮设置点击事件
btnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//跳转到注册界面
startActivity(new Intent(LoginActivity.this, RegisterActivity.class));
LoginActivity.this.finish(); //结束当前界面
}
});
}
/**
*
*
* @param username
* @param password
*/
private void tryToLogin(String username, String password) {
String postUrl = HttpUtil.HOST + "api/user/login";
//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");
//给用户的钱包余额设定金额
ShareUtils.putInt(getApplicationContext(), "money", data.getInt("money"));
ShareUtils.putInt(getApplicationContext(), "user_id", data.getInt("id"));
ShareUtils.putString(getApplicationContext(), "user_true_name", data.getString("nickname"));
ShareUtils.putString(getApplicationContext(), "user_true_phone", data.getString("phone"));
ShareUtils.putString(getApplicationContext(), "user_true_mail", data.getString("email"));
//登录成功,跳转到菜单展示的主页面
Intent intent = new Intent(LoginActivity.this, OrderActivity.class);
startActivity(intent);
finish();
} else {
showDialog(res.getString("msg"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailed(int what, Response<JSONObject> response) {
Intent intent = new Intent(LoginActivity.this, OrderActivity.class);
startActivity(intent);
}
@Override
public void onFinish(int what) {
}
});
}
/**
* 便
*
* @param msg
*/
private void showDialog(String msg) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(msg)
.setCancelable(false)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
}
}

@ -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,398 @@
package com.sbw.atrue.Order.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.appcompat.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.sbw.atrue.Order.Entity.Food;
import com.sbw.atrue.Order.Entity.Product;
import com.sbw.atrue.Order.Util.FoodAdapter;
import com.sbw.atrue.Order.R;
import com.sbw.atrue.Order.Util.FoodFctory;
import com.sbw.atrue.Order.Util.HttpUtil;
import com.sbw.atrue.Order.Util.MyListener;
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.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* ClassName: OrderActivity <br>
* description: <br>
* author: -13042299081 <br>
* Date: 2019/2/18 21:03
*/
public class OrderActivity extends AppCompatActivity {
//从生产类中加载系统存储的菜单列表
// private Food[] foods = FoodFctory.Beef;
private List<Food> foodList = new ArrayList<>();
private DrawerLayout mDrawerLayout;
private FoodAdapter adapter;
private SwipeRefreshLayout swipeRefresh;
private int first = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order);
//导入Toolbar的自定义布局形式
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//导入滑动菜单
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
NavigationView navView = (NavigationView) findViewById(R.id.nav_view);
//获得ActionBar的实例虽然此ActionBar具体实现是由ToolBar来完成的
final ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
//将ActionBar的导航按钮HomeAsUp显示出来Toolbar标题栏最左侧的按钮图标默认为箭头含义为返回上一级活动
actionBar.setDisplayHomeAsUpEnabled(true);
//更改导航按钮HomeAsUp的默认图标箭头改为导航键
//actionBar.setHomeAsUpIndicator(R.drawable.ic_comment);
}
//设置滑动菜单的按钮点击事件
navView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
//点击任意菜单选项,则将滑动菜单关闭
// mDrawerLayout.closeDrawers();
menuItem.setChecked(true);
switch (menuItem.getItemId()) {
case R.id.nav_Order:
//跳转到订单界面
orderDetail(new MyListener<JSONArray>() {
@Override
public void onSuccess(JSONArray array) throws JSONException {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.length(); i++) {
sb.append(getDataString(array.getJSONObject(i)));
}
Log.e("demo", "onSuccess: "+sb.toString() );
Intent intent = new Intent(OrderActivity.this, ReadOrderActivity.class);
intent.putExtra("content", sb.toString());
startActivity(intent);
}
});
break;
case R.id.nav_money:
//跳转到钱包界面
startActivity(new Intent(OrderActivity.this, MyMoneyActivity.class));
break;
case R.id.nav_setting:
//跳转到钱包界面
startActivity(new Intent(OrderActivity.this, SettingActivity.class));
break;
case R.id.nav_logout:
//跳转到登陆界面
startActivity(new Intent(OrderActivity.this, LoginActivity.class));
//结束当前界面
OrderActivity.this.finish();
break;
default:
break;
}
return true;
}
});
//悬浮按键的设置
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//跳转到登陆界面
startActivity(new Intent(OrderActivity.this, ShoppingActivity.class));
}
});
//显示菜单的控件逻辑
initFruits();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(layoutManager);
adapter = new FoodAdapter(foodList);
recyclerView.setAdapter(adapter);
//刷新菜单的控件逻辑
swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
swipeRefresh.setColorSchemeResources(R.color.colorPrimary);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refreshfoods();
}
});
}
/**
*
*/
private void initDatas(String demo) {
}
private String getDataString(JSONObject data) throws JSONException {
double totalPrice = 0; //购买商品总价
ArrayList<Product> selectedProducts = new ArrayList<>();
JSONArray array = data.getJSONArray("selectedProducts");
for (int i = 0; i < array.length(); i++) {
JSONObject jsonObject = array.getJSONObject(i);
int id = 0;
String name = jsonObject.getString("foodName");
double price = jsonObject.getDouble("price");
// JSONObject product=jsonObject.getJSONObject("product");
// String picture = product.getString("picture");
int sale = 1;
String shopName = "";
String detail = "";
boolean isShowSubBtn = true;
Product product = new Product(id, name, price, "", sale, shopName, detail, isShowSubBtn);
product.setSelctCount(jsonObject.getInt("num"));
selectedProducts.add(product);
}
String name = data.getString("userName");
String phone = data.getString("phone"); //从意图获取手机号
String tableId = data.getString("tableId"); //从意图获取用餐桌号
StringBuilder orderResult = new StringBuilder(); //新建订单结果信息
orderResult.append("\t\t\t\t\t\t\t订单信息如下\n\n");//添加文本内容
orderResult.append("*************************\n");
orderResult.append("商品名\t\t\t数量\t\t\t\t价格\n");
for (int i = 0; i < selectedProducts.size(); i++) { //遍历商品列表并往文本写入商品信息
Product product = selectedProducts.get(i);
if (product.getName().length() == 2) {
orderResult.append(product.getName() + "\t\t\t\t\t\t\t " + product.getSelectedCount() + " \t\t\t\t\t" + product.getPrice() * product.getSelectedCount() + "\n");
} else {
orderResult.append(product.getName() + "\t\t\t\t\t" + product.getSelectedCount() + "\t\t\t\t\t" + product.getPrice() * product.getSelectedCount() + "\n");
}
totalPrice += product.getPrice() * product.getSelectedCount(); //设置商品总价
}
orderResult.append("*************************");
orderResult.append("\n共计" + totalPrice + "元\n\n");
orderResult.append("\t\t\t\t\t\t\t您的信息如下\n");
orderResult.append("*************************\n");
orderResult.append("姓名:" + name + "\n");
orderResult.append("电话:" + phone + "\n");
orderResult.append("桌号:" + tableId + "\n");
//获取当前系统时间(记录下单时间)
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
String nowTime = simpleDateFormat.format(date);
orderResult.append("时间:" + nowTime + "\n");
//将订单结果信息设置到订单信息显示文字控件
return orderResult.toString();
}
private void orderDetail(final MyListener<JSONArray> literer) {
String postUrl = HttpUtil.HOST + "api/order/list";
//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) {
literer.onSuccess(res.getJSONArray("data"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailed(int what, Response<JSONObject> response) {
}
@Override
public void onFinish(int what) {
}
});
}
/**
*
*/
private void refreshfoods() {
new Thread(new Runnable() {
@Override
public void run() {
try {
//为了避免程序刷新太快先让线程睡眠2秒
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//从子线程切回到主线程从而可以更改UI
runOnUiThread(new Runnable() {
@Override
public void run() {
//向菜单中增加新菜
if (first == 0) {
Food WanZi = new Food("牛肉丸", "R.drawable.wanzi", "牛肉丸是潮汕美食啊!!!");
foodList.add(WanZi);
first = 1;
}
//通知适配器数据发生了变化用于RecycleView自动更新显示项
adapter.notifyDataSetChanged();
//刷新结束,将刷新进度条隐藏
swipeRefresh.setRefreshing(false);
//显示更新结果的弹框通知,告知用户更新情况
AlertDialog.Builder builder = new AlertDialog.Builder(OrderActivity.this);
builder.setMessage("菜单更新成功啦~")
.setCancelable(false)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
}
}).start();
}
/**
* Food
*/
private void initFruits() {
foodList.clear();
String postUrl = HttpUtil.HOST + "api/food/list";
//1.创建一个队列
RequestQueue queue = NoHttp.newRequestQueue();
//2.创建消息请求 参数1:String字符串,传网址 参数2:请求方式
final Request<JSONObject> request = NoHttp.createJsonObjectRequest(postUrl, RequestMethod.POST);
//3.利用队列去添加消息请求
//使用request对象添加上传的对象添加键与值,post方式添加上传的数据
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) {
JSONArray array = res.getJSONArray("data");
for (int i = 0; i < array.length(); i++) {
JSONObject data = array.getJSONObject(i);
Food food = new Food(data.getString("name"), data.getString("imageId"), data.getString("description"));
foodList.add(food);
}
adapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailed(int what, Response<JSONObject> response) {
}
@Override
public void onFinish(int what) {
}
});
}
/**
* toolbar.xml
*
* @param menu
* @return
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar, menu);
return true;
}
/**
* Toolbat
*
* @param item
* @return
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
//android.R.id.home是标题栏最左侧按键HomeAsUp的Id
case android.R.id.home:
//将滑动菜单展示出来GravityCompat.START参数与XML文件定义的保持一致
mDrawerLayout.openDrawer(GravityCompat.START);
break;
case R.id.backup:
Toast.makeText(this, "You click Backup", Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(this, "You click Delete", Toast.LENGTH_SHORT).show();
break;
case R.id.setting:
Toast.makeText(this, "You click Setting", Toast.LENGTH_SHORT).show();
break;
default:
}
return true;
}
}

@ -0,0 +1,137 @@
package com.sbw.atrue.Order.Activity;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import com.sbw.atrue.Order.Entity.Order;
import com.sbw.atrue.Order.Entity.Product;
import com.sbw.atrue.Order.Entity.ProductOrder;
import com.sbw.atrue.Order.R;
import org.litepal.crud.DataSupport;
import java.util.List;
/**
* FileName: ReadOrderActivity <br>
* Description: <br>
* Author: -13042299081 <br>
* Date: 2019/4/9 10:52
*/
public class ReadOrderActivity extends Activity {
private TextView tvResult; //订单信息显示文字控件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_readorder);
tvResult = (TextView) findViewById(R.id.tv_result);
//从数据库中读取订单信息
//readFromSqlite();
//暴力输出订单信息
readBaoLi();
}
/**
* LitePalSQlite
*/
private void readFromSqlite(){
//从SQLite数据库读取历史订单列表
List<Order> orders=DataSupport.findAll(Order.class);
//遍历订单列表并输出订单信息
for(Order order:orders){
StringBuilder orderResult = new StringBuilder(); //新建订单结果信息
orderResult.append("\t\t\t\t\t\t\t订单信息如下\n");//添加文本内容
orderResult.append("*************************\n");
orderResult.append("商品名\t\t\t数量\t\t\t\t价格\n");
double totalPrice = 0; //购买商品总价
for (int i = 0; i < order.getSelectedProducts().size(); i++) { //遍历商品列表并往文本写入商品信息
ProductOrder product = order.getSelectedProducts().get(i);
if(product.getFoodName().length()==2){
orderResult.append(product.getFoodName() + "\t\t\t\t\t\t\t " + product.getNum() + " \t\t\t\t\t" + product.getPrice() + "\n");
}else{
orderResult.append(product.getFoodName() + "\t\t\t\t\t" + product.getNum() + "\t\t\t\t\t" + product.getPrice()+ "\n");
}
totalPrice += product.getPrice(); //设置商品总价
}
orderResult.append("*************************");
orderResult.append("\n共计" + totalPrice + "元\n\n");
orderResult.append("\t\t\t\t\t\t\t您的信息如下\n");
orderResult.append("*************************\n");
orderResult.append("姓名:" + order.getUserName() + "\n");
orderResult.append("电话:" + order.getPhone() + "\n");
orderResult.append("桌号:" + order.getTableId()+ "\n");
orderResult.append("时间:"+ order.getTime()+ "\n");
//将订单结果信息设置到订单信息显示文字控件
tvResult.setText(orderResult);
}
}
/**
*
*/
private void readBaoLi(){
StringBuilder orderResult = new StringBuilder(); //新建订单结果信息
orderResult.append("\t\t\t\t\t\t\t订单1\n");//添加文本内容
orderResult.append("*************************\n");
orderResult.append("商品名\t\t\t数量\t\t\t\t价格\n");
orderResult.append("牛肉丸"+ "\t\t\t\t\t" + 2 + " \t\t\t\t\t" + 76 + "\n");
orderResult.append("嫩肉"+ "\t\t\t\t\t\t\t " + 2 + " \t\t\t\t\t" + 76 + "\n");
orderResult.append("五花趾"+ "\t\t\t\t\t" + 1 + " \t\t\t\t\t" + 38 + "\n");
orderResult.append("*************************");
orderResult.append("\n共计" + 152 + "元\n");
orderResult.append("姓名:" + "沈滨伟" + "\n");
orderResult.append("电话:" + "13042299081" + "\n");
orderResult.append("桌号:" + "10"+ "\n");
orderResult.append("时间:"+ "2019年4月10日 15:11:35"+ "\n");
orderResult.append("\n\n");
orderResult.append("\t\t\t\t\t\t\t订单2\n");
orderResult.append("*************************\n");
orderResult.append("商品名\t\t\t数量\t\t\t\t价格\n");
orderResult.append("雪花"+ "\t\t\t\t\t\t\t " + 2 + " \t\t\t\t\t" + 100 + "\n");
orderResult.append("吊龙"+ "\t\t\t\t\t\t\t " + 1 + " \t\t\t\t\t" + 40 + "\n");
orderResult.append("*************************");
orderResult.append("\n共计" + 140 + "元\n");
orderResult.append("姓名:" + "沈滨伟" + "\n");
orderResult.append("电话:" + "13042299081" + "\n");
orderResult.append("桌号:" + "10"+ "\n");
orderResult.append("时间:"+ "2019年4月11日 19:24:30"+ "\n");
orderResult.append("\n\n");
orderResult.append("\t\t\t\t\t\t\t订单3\n");
orderResult.append("*************************\n");
orderResult.append("商品名\t\t\t数量\t\t\t\t价格\n");
orderResult.append("胸口朥"+ "\t\t\t\t\t" + 2 + " \t\t\t\t\t" + 90 + "\n");
orderResult.append("嫩肉"+ "\t\t\t\t\t\t\t " + 2 + " \t\t\t\t\t" + 76 + "\n");
orderResult.append("五花趾"+ "\t\t\t\t\t" + 1 + " \t\t\t\t\t" + 38 + "\n");
orderResult.append("吊龙"+ "\t\t\t\t\t\t\t " + 2 + " \t\t\t\t\t" + 80 + "\n");
orderResult.append("*************************");
orderResult.append("\n共计" + 284 + "元\n");
orderResult.append("姓名:" + "沈滨伟" + "\n");
orderResult.append("电话:" + "13042299081" + "\n");
orderResult.append("桌号:" + "10"+ "\n");
orderResult.append("时间:"+ "2019年4月12日 08:15:45"+ "\n");
orderResult.append("\n\n");
orderResult.append("\t\t\t\t\t\t\t订单4\n");
orderResult.append("*************************\n");
orderResult.append("商品名\t\t\t数量\t\t\t\t价格\n");
orderResult.append("三花趾"+ "\t\t\t\t\t" + 2 + " \t\t\t\t\t" + 72 + "\n");
orderResult.append("胸口朥"+ "\t\t\t\t\t" + 2 + " \t\t\t\t\t" + 90 + "\n");
orderResult.append("嫩肉"+ "\t\t\t\t\t\t\t " + 2 + " \t\t\t\t\t" + 76 + "\n");
orderResult.append("五花趾"+ "\t\t\t\t\t" + 1 + " \t\t\t\t\t" + 38 + "\n");
orderResult.append("嫩肉"+ "\t\t\t\t\t\t\t " + 3 + " \t\t\t\t\t" + 120 + "\n");
orderResult.append("*************************");
orderResult.append("\n共计" + 399 + "元\n");
orderResult.append("姓名:" + "沈滨伟" + "\n");
orderResult.append("电话:" + "13042299081" + "\n");
orderResult.append("桌号:" + "10"+ "\n");
orderResult.append("时间:"+ "2019年4月15日 11:24:06"+ "\n");
//将订单结果信息设置到订单信息显示文字控件
tvResult.setText(getIntent().getStringExtra("content"));
}
}

@ -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,258 @@
package com.sbw.atrue.Order.Activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.sbw.atrue.Order.Entity.Food;
import com.sbw.atrue.Order.Entity.Product;
import com.sbw.atrue.Order.R;
import com.sbw.atrue.Order.Util.FoodFctory;
import com.sbw.atrue.Order.Util.HttpUtil;
import com.sbw.atrue.Order.Util.ProductListAdapter;
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.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class ShoppingActivity extends Activity {
public static ShoppingActivity mInstance = null; //当前对象的实例本身
private ListView lvProduct; //商品展示列表控件
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; //商品列表适配器
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shopping);
initViews(); //初始化页面控件
initDatas(); //初始化数据
initEvents(); //初始化控件事件
}
private void initDatas() {
productsData = new ArrayList<>();
String postUrl = HttpUtil.HOST + "api/food/productList";
//1.创建一个队列
RequestQueue queue = NoHttp.newRequestQueue();
//2.创建消息请求 参数1:String字符串,传网址 参数2:请求方式
final Request<JSONObject> request = NoHttp.createJsonObjectRequest(postUrl, RequestMethod.POST);
//3.利用队列去添加消息请求
//使用request对象添加上传的对象添加键与值,post方式添加上传的数据
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) {
JSONArray array = res.getJSONArray("data");
for (int i = 0; i < array.length(); i++) {
JSONObject data = array.getJSONObject(i);
Product product = new Product(data.getInt("id"),
data.getString("name"),
data.getDouble("price"),
data.getString("picture"),
data.getInt("sale"),
data.getString("shopName"),
data.getString("detail"), true);
productsData.add(product);
}
productListAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailed(int what, Response<JSONObject> response) {
}
@Override
public void onFinish(int what) {
}
});
}
//初始化页面控件
private void initViews() {
lvProduct = (ListView) findViewById(R.id.lv_product);
tvSelected = (TextView) findViewById(R.id.tv_selected);
tvTotal = (TextView) findViewById(R.id.tv_total);
btnTakeOrder = (Button) findViewById(R.id.btn_take_order);
btnSortByNew = (Button) findViewById(R.id.btn_sort_by_new);
btnSortByPrice = (Button) findViewById(R.id.btn_sort_by_price);
btnSortBySale = (Button) findViewById(R.id.btn_sort_by_sale);
btnSortByAll = (Button) findViewById(R.id.btn_sort_by_all);
}
//初始化控件事件
private void initEvents() {
mInstance = this; //设置实例等于当前对象本身
//将数据源放入适配器中
productListAdapter = new ProductListAdapter(this, productsData);
//给商品展示列表控件设置顶部分隔线
lvProduct.addHeaderView(new View(this));
//给商品展示列表控件设置适配器
lvProduct.setAdapter(productListAdapter);
//给下单按钮添加点击事件
btnTakeOrder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (selectedProducts.size() != 0) { //已选择商品数据不为空
Intent intent = new Intent(getApplicationContext(), InputActivity.class); //新建意图
intent.putParcelableArrayListExtra("selectedProducts", selectedProducts); //设置已选择的商品数据
startActivity(intent); //启动信息输入界面
} else { //已选择商品数据为空
showDialog("购物车为空,请选择商品!");
}
}
});
//给按新品排序按钮设置点击事件
btnSortByNew.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { //点击事件
Collections.sort(productsData, new Comparator<Product>() { //对商品数据进行排序
@Override
public int compare(Product product1, Product product2) { //比较商品
//如果本商品被选择次数大于第二个商品
if (product1.getSelectedCount() > product2.getSelectedCount()) {
return 1; //返回正数代表本商品大于第二个商品
}
return -1; //返回负数代表本商品小于第二个商品
}
});
productListAdapter.notifyDataSetChanged(); //通知系统数据改变
}
});
//给按销量排序按钮设置点击事件
btnSortBySale.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { //点击事件
Collections.sort(productsData, new Comparator<Product>() { //对商品数据进行排序
@Override
public int compare(Product product1, Product product2) { //比较商品
//如果本商品的销量小于第二个商品
if (product1.getSale() < product2.getSale()) {
return 1; //返回正数代表本商品大于第二个商品
}
return -1; //返回负数代表本商品小于第二个商品
}
});
productListAdapter.notifyDataSetChanged(); //通知系统数据改变
}
});
//给按价格排序按钮设置点击事件
btnSortByPrice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { //点击事件
Collections.sort(productsData, new Comparator<Product>() { //对商品数据进行排序
@Override
public int compare(Product product1, Product product2) { //比较商品
//如果本商品的价格大于第二个商品
if (product1.getPrice() > product2.getPrice()) {
return 1; //返回正数代表本商品大于第二个商品
}
return -1; //返回负数代表本商品小于第二个商品
}
});
productListAdapter.notifyDataSetChanged(); //通知系统数据改变
}
});
//给按综合排序按钮设置点击事件
btnSortByAll.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { //点击事件
Collections.sort(productsData, new Comparator<Product>() { //对商品数据进行排序
@Override
public int compare(Product product1, Product product2) { //比较商品
//如果本商品的价格大于第二个商品
if (product1.getId() > product2.getId()) {
return 1; //返回正数代表本商品大于第二个商品
}
return -1; //返回负数代表本商品小于第二个商品
}
});
productListAdapter.notifyDataSetChanged(); //通知系统数据改变
}
});
}
//设置被选择商品数量与价格
public void setSelectedCountAndPrice(int selectedCount, int totalPrice) {
tvSelected.setText(String.valueOf(selectedCount)); //在界面上设置已选择商品数量的信息
tvTotal.setText(String.valueOf(totalPrice)); //在界面上设置已选择商品总价的信息
if (selectedCount == 0 && totalPrice == 0) { //当被选择商品数量和总价都为0时
for (Product product : productsData) { //遍历商品列表
product.clearZero(); //将每一项商品的选择次数归零与不显示减去按钮
}
selectedProducts.clear(); //清空已选择商品列表
productListAdapter.notifyDataSetChanged(); //通知系统数据已改变
}
}
//设置被选择的商品数据
public void setSelectedProducts(ArrayList<Product> data) {
this.selectedProducts = data; //获取被选择商品数据
productListAdapter.setSelectedProducts(data); //设置被选择商品数据到商品适配器
}
/**
* 便
*
* @param msg
*/
private void showDialog(String msg) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(msg)
.setCancelable(false)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
}
}

@ -0,0 +1,459 @@
package com.sbw.atrue.Order.Activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.google.gson.Gson;
import com.sbw.atrue.Order.Entity.Order;
import com.sbw.atrue.Order.Entity.ProductOrder;
import com.sbw.atrue.Order.R;
import com.sbw.atrue.Order.Entity.Product;
import com.sbw.atrue.Order.Util.HttpUtil;
import com.sbw.atrue.Order.Util.MyListener;
import com.sbw.atrue.Order.Util.ShareUtils;
import com.yanzhenjie.nohttp.NoHttp;
import com.yanzhenjie.nohttp.RequestMethod;
import com.yanzhenjie.nohttp.rest.JsonObjectRequest;
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.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.litepal.tablemanager.Connector;
public class SuccessActivity extends Activity {
private static final String TAG = SuccessActivity.class.getName();
private TextView tvResult; //订单信息显示文字控件
private Button btnContinueBuy; //加菜按钮
private Button btnPay; //结账按钮
private ArrayList<Product> selectedProducts = new ArrayList<Product>(); //被选择的的商品数据
private String nowTime;//订单提交时间
private double totalPrice = 0; //购买商品总价
private boolean ispay = false; //判断订单是否已被支付
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_success);
initViews(); //初始化页面控件
initDatas(); //初始化页面数据
initEvents(); //初始化控件事件
}
//初始化页面控件
private void initViews() {
tvResult = (TextView) findViewById(R.id.tv_result);
btnContinueBuy = (Button) findViewById(R.id.btn_continue_buy);
btnPay = (Button) findViewById(R.id.btn_pay);
}
/**
*
*/
private void initEvents() {
showDialog("您的订单提交成功!请您及时支付!");
//给加菜按钮设置点击事件
btnContinueBuy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ispay) {
//跳转到购物界面
startActivity(new Intent(getApplicationContext(), ShoppingActivity.class));
//结束当前界面
SuccessActivity.this.finish();
} else {
showDialog("您尚未支付当前订单!请结账后再加菜!");
}
}
});
//给结账按钮设置点击事件
btnPay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//保存订单信息至SQLite数据库中可惜Litepal框架使用失败。
// transformData();
MyListener<JSONObject> stringMyListener = new MyListener<JSONObject>() {
@Override
public void onSuccess(JSONObject data) throws JSONException {
if (data.getInt("status") != 0) {
showDialog(data.getString("msg"));
} else {
int myMoney = ShareUtils.getInt(SuccessActivity.this, "money", 1);
if (totalPrice > myMoney) {
//当账户余额的钱不足以支付当前订单时
showDialogNoMoney();
} else {
myMoney -= totalPrice;
//更新账户余额
ShareUtils.putInt(SuccessActivity.this, "money", myMoney);
//将订单标记为“已结账”,并将结账按钮设置为不可见状态
ispay = true;
btnPay.setVisibility(View.INVISIBLE);
//结账成功后,客户选择返回主界面,还是继续加菜
showDialogFinish();
}
}
}
};
payOrder(getIntent().getStringExtra("orderId"), stringMyListener);
}
});
}
private void payOrder(String orderId, final MyListener<JSONObject> listener) {
String postUrl = HttpUtil.HOST + "api/order/pay";
//1.创建一个队列
RequestQueue queue = NoHttp.newRequestQueue();
//2.创建消息请求 参数1:String字符串,传网址 参数2:请求方式
final Request<JSONObject> request = NoHttp.createJsonObjectRequest(postUrl, RequestMethod.POST);
//3.利用队列去添加消息请求
//使用request对象添加上传的对象添加键与值,post方式添加上传的数据
request.add("orderId", orderId);
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) {
Log.w(TAG, "onSucceed: " + res.getString("data"));
listener.onSuccess(res);
} else {
showDialog(res.getString("msg"));
}
} catch (Exception e) {
e.printStackTrace();
showDialog(e.getMessage());
}
}
@Override
public void onFailed(int what, Response<JSONObject> response) {
}
@Override
public void onFinish(int what) {
}
});
}
/**
*
*/
private void initDatas() {
Intent otherIntent = getIntent(); //获取信息输入界面传来的意图
selectedProducts = otherIntent.getParcelableArrayListExtra("selectedProducts"); //从意图中获取被选择的的商品数据
String name = otherIntent.getStringExtra("name"); //从意图获取客户姓名
String phone = otherIntent.getStringExtra("phone"); //从意图获取手机号
String tableId = otherIntent.getStringExtra("table"); //从意图获取用餐桌号
StringBuilder orderResult = new StringBuilder(); //新建订单结果信息
orderResult.append("\t\t\t\t\t\t\t订单信息如下\n");//添加文本内容
orderResult.append("*************************\n");
orderResult.append("商品名\t\t\t数量\t\t\t\t价格\n");
for (int i = 0; i < selectedProducts.size(); i++) { //遍历商品列表并往文本写入商品信息
Product product = selectedProducts.get(i);
if (product.getName().length() == 2) {
orderResult.append(product.getName() + "\t\t\t\t\t\t\t " + product.getSelectedCount() + " \t\t\t\t\t" + product.getPrice() * product.getSelectedCount() + "\n");
} else {
orderResult.append(product.getName() + "\t\t\t\t\t" + product.getSelectedCount() + "\t\t\t\t\t" + product.getPrice() * product.getSelectedCount() + "\n");
}
totalPrice += product.getPrice() * product.getSelectedCount(); //设置商品总价
}
orderResult.append("*************************");
orderResult.append("\n共计" + totalPrice + "元\n\n");
orderResult.append("\t\t\t\t\t\t\t您的信息如下\n");
orderResult.append("*************************\n");
orderResult.append("姓名:" + name + "\n");
orderResult.append("电话:" + phone + "\n");
orderResult.append("桌号:" + tableId + "\n");
//获取当前系统时间(记录下单时间)
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
nowTime = simpleDateFormat.format(date);
orderResult.append("时间:" + nowTime + "\n");
//将订单结果信息设置到订单信息显示文字控件
tvResult.setText(orderResult);
}
/**
* 便
*/
private void transformData() {
Connector.getDatabase();//创建数据库
Intent otherIntent = getIntent(); //获取信息输入界面传来的意图
selectedProducts = otherIntent.getParcelableArrayListExtra("selectedProducts"); //从意图中获取被选择的的商品数据
String name = otherIntent.getStringExtra("name"); //从意图获取客户姓名
String phone = otherIntent.getStringExtra("phone"); //从意图获取手机号
String tableId = otherIntent.getStringExtra("table"); //从意图获取用餐桌号
List<ProductOrder> productOrders = new ArrayList<>();
ProductOrder productOrder = new ProductOrder();
for (int i = 0; i < selectedProducts.size(); i++) { //遍历商品列表并存入到productOrders列表中
Product product = selectedProducts.get(i);
productOrder.setFoodName(product.getName());
productOrder.setNum(product.getSelectedCount());
productOrder.setPrice(product.getPrice() * product.getSelectedCount());
productOrders.add(productOrder);
}
Order newOrder = new Order();
newOrder.setSelectedProducts(productOrders);
newOrder.setUserName(name);
newOrder.setPhone(phone);
newOrder.setTableId(tableId);
newOrder.setTime(nowTime);
String postUrl = HttpUtil.HOST + "api/user/login";
//1.创建一个队列
RequestQueue queue = NoHttp.newRequestQueue();
//2.创建消息请求 参数1:String字符串,传网址 参数2:请求方式
final Request<JSONObject> request = NoHttp.createJsonObjectRequest(postUrl, RequestMethod.POST);
//3.利用队列去添加消息请求
//使用request对象添加上传的对象添加键与值,post方式添加上传的数据
request.setDefineRequestBodyForJson(new Gson().toJson(newOrder));
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");
//给用户的钱包余额设定金额
ShareUtils.putInt(getApplicationContext(), "money", data.getInt("money"));
ShareUtils.putInt(getApplicationContext(), "user_id", data.getInt("id"));
ShareUtils.putString(getApplicationContext(), "user_true_name", data.getString("nickname"));
ShareUtils.putString(getApplicationContext(), "user_true_phone", data.getString("phone"));
ShareUtils.putString(getApplicationContext(), "user_true_mail", data.getString("email"));
//登录成功,跳转到菜单展示的主页面
Intent intent = new Intent(getApplicationContext(), OrderActivity.class);
startActivity(intent);
finish();
} else {
showDialog(res.getString("msg"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailed(int what, Response<JSONObject> response) {
}
@Override
public void onFinish(int what) {
}
});
}
/**
* 便
*
* @param msg
*/
private void showDialog(String msg) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(msg)
.setCancelable(false)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
}
/**
*
*/
private void showDialogNoMoney() {
AlertDialog.Builder dialog = new AlertDialog.Builder(SuccessActivity.this);
dialog.setTitle("账户余额不足\n\n");
dialog.setMessage("请您到充值页面进行充值后再结账!");
dialog.setCancelable(false);
dialog.setPositiveButton("好的", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(getApplicationContext(), MyMoneyActivity.class));
}
});
dialog.setNegativeButton("不吃了", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(SuccessActivity.this, "您选择不吃了!", Toast.LENGTH_SHORT).show();
}
});
dialog.show();
}
/**
*
*/
private void showDialogFinish() {
AlertDialog.Builder dialog = new AlertDialog.Builder(SuccessActivity.this);
dialog.setTitle("订单支付成功!\n\n");
dialog.setMessage("您是否想继续加菜?");
dialog.setCancelable(false);
dialog.setPositiveButton("是的", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(SuccessActivity.this, "请继续点餐~", Toast.LENGTH_SHORT).show();
}
});
dialog.setNegativeButton("不用了", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(SuccessActivity.this, "感谢您的光临!祝您用餐愉快!", Toast.LENGTH_SHORT).show();
//跳转到购物界面
startActivity(new Intent(getApplicationContext(), OrderActivity.class));
SuccessActivity.this.finish(); //结束当前界面
}
});
dialog.show();
}
/**
*
*/
private void initDatas(String demo) {
tvResult.setText("ss\n\n\ndsss");
orderDetail(getIntent().getStringExtra("orderId"), new MyListener<JSONObject>() {
@Override
public void onSuccess(JSONObject data) throws JSONException {
selectedProducts = new ArrayList<>();
JSONArray array = data.getJSONArray("selectedProducts");
for (int i = 0; i < array.length(); i++) {
JSONObject jsonObject = array.getJSONObject(i);
int id = 0;
String name = jsonObject.getString("foodName");
double price = jsonObject.getDouble("price");
String picture = jsonObject.getJSONObject("product").getString("picture");
int sale = 1;
String shopName = "";
String detail = "";
boolean isShowSubBtn = true;
Product product = new Product(id, name, price, picture, sale, shopName, detail, isShowSubBtn);
product.setSelctCount(jsonObject.getInt("num"));
selectedProducts.add(product);
}
Log.w(TAG, "onSucceed: " + selectedProducts.size());
String name = data.getString("userName");
String phone = data.getString("phone"); //从意图获取手机号
String tableId = data.getString("tableId"); //从意图获取用餐桌号
StringBuilder orderResult = new StringBuilder(); //新建订单结果信息
orderResult.append("\t\t\t\t\t\t\t订单信息如下\n\n");//添加文本内容
orderResult.append("*************************\n");
orderResult.append("商品名\t\t\t数量\t\t\t\t价格\n");
for (int i = 0; i < SuccessActivity.this.selectedProducts.size(); i++) { //遍历商品列表并往文本写入商品信息
Product product = SuccessActivity.this.selectedProducts.get(i);
if (product.getName().length() == 2) {
orderResult.append(product.getName() + "\t\t\t\t\t\t\t " + product.getSelectedCount() + " \t\t\t\t\t" + product.getPrice() * product.getSelectedCount() + "\n");
} else {
orderResult.append(product.getName() + "\t\t\t\t\t" + product.getSelectedCount() + "\t\t\t\t\t" + product.getPrice() * product.getSelectedCount() + "\n");
}
totalPrice += product.getPrice() * product.getSelectedCount(); //设置商品总价
}
Log.w(TAG, "onSucceed: " + totalPrice);
orderResult.append("*************************");
orderResult.append("\n共计" + totalPrice + "元\n\n");
orderResult.append("\t\t\t\t\t\t\t您的信息如下\n");
orderResult.append("*************************\n");
orderResult.append("姓名:" + name + "\n");
orderResult.append("电话:" + phone + "\n");
orderResult.append("桌号:" + tableId + "\n");
//获取当前系统时间(记录下单时间)
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
nowTime = simpleDateFormat.format(date);
orderResult.append("时间:" + nowTime + "\n");
//将订单结果信息设置到订单信息显示文字控件
Log.w(TAG, "onSucceed: " + orderResult);
tvResult.setText(orderResult);
Log.w(TAG, "onSucceed: " + orderResult);
initEvents(); //初始化控件事件
}
});
}
private void orderDetail(String orderId, final MyListener<JSONObject> literer) {
String postUrl = HttpUtil.HOST + "api/order/orderDetail";
//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));
request.add("orderId", orderId);
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) {
Log.w(TAG, "onSucceed: " + res.getJSONObject("data").toString());
literer.onSuccess(res.getJSONObject("data"));
} else {
showDialog(res.getString("msg"));
}
} catch (Exception e) {
e.printStackTrace();
showDialog(e.getMessage());
}
}
@Override
public void onFailed(int what, Response<JSONObject> response) {
}
@Override
public void onFinish(int what) {
}
});
}
}

@ -0,0 +1,37 @@
package com.sbw.atrue.Order.Entity;
import java.io.Serializable;
/**
* ClassName: Food <br>
* description: Intent <br>
* author: -13042299081 <br>
* Date: 2019/2/18 22:08
*/
public class Food implements Serializable {
//菜品名称
private String name;
/**
* R.drawable.mango
*/
private String imageId;
//菜品描述
private String description;
public Food(String name, String imageId,String description) {
this.name = name;
this.imageId = imageId;
this.description=description;
}
public String getName() {
return name;
}
public String getImageId() {
return imageId;
}
public String getDescription(){return description;}
}

@ -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,107 @@
package com.sbw.atrue.Order.Util;
import android.content.Context;
import android.content.Intent;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.sbw.atrue.Order.Activity.FoodActivity;
import com.sbw.atrue.Order.Entity.Food;
import com.sbw.atrue.Order.R;
import java.util.List;
/**
* ClassName: FoodAdapter <br>
* description: RecycleView <br>
* author: -13042299081 <br>
* Date: 2019/2/18 21:03
*/
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.ViewHolder>{
private static final String TAG = "FoodAdapter";
private Context mContext;
private List<Food> mfoodList;
/**
* foodAdapter
*/
static class ViewHolder extends RecyclerView.ViewHolder {
CardView cardView;
ImageView foodImage;
TextView foodName;
//构造函数
public ViewHolder(View view) {
super(view);
cardView = (CardView) view;
foodImage = (ImageView) view.findViewById(R.id.food_image);
foodName = (TextView) view.findViewById(R.id.food_name);
}
}
/**
* foodAdapter
* @param foodList
*/
public FoodAdapter(List<Food> foodList) {
mfoodList = foodList;
}
/**
* ViewHolder
* @param parent
* @param viewType
* @return ViewHolderonBindViewHolder
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (mContext == null) {
mContext = parent.getContext();
}
//动态加载布局文件(菜品的简单展示布局,即图片+菜名并并把加载出来的布局传入到构造函数中从而创建ViewHolder实例
View view = LayoutInflater.from(mContext).inflate(R.layout.food_item, parent, false);
final ViewHolder holder = new ViewHolder(view);
//如果用户点击菜品卡片,则跳转到显示相应的菜品详情的活动中去
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getAdapterPosition();
Food food = mfoodList.get(position);
Intent intent = new Intent(mContext, FoodActivity.class);
//将用户点击的菜品的对象传递到下一个活动菜品详情展示FoodActivity
intent.putExtra("Food_Choose",food);
mContext.startActivity(intent);
}
});
return holder;
}
/**
* RecycleView+
* @param holder onCreateViewHolderViewHolder
* @param position
*/
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Food food = mfoodList.get(position);
holder.foodName.setText(food.getName());
//使用Glide加载图片不用担心像素太高导致内存溢出
Glide.with(mContext).load(food.getImageId()).into(holder.foodImage);
}
/**
*
* @return
*/
@Override
public int getItemCount() {
return mfoodList.size();
}
}

@ -0,0 +1,55 @@
package com.sbw.atrue.Order.Util;
import com.sbw.atrue.Order.Entity.Food;
import com.sbw.atrue.Order.Entity.Product;
import com.sbw.atrue.Order.R;
import java.util.ArrayList;
import java.util.List;
/**
* FileName: FoodFctory <br>
* Description: <br>
* Author: -13042299081 <br>
* Date: 2019/2/18 22:21
*/
public class FoodFctory {
// static public Food[] Beef={
// //备注文字如果想要有换行效果的话,直接上\n即可
// new Food("雪花",R.drawable.xuehua,"\t\t\t\t雪花是牛脖子上的凸起的一块肉是牛运动最为频繁的一块活肉也是牛身上最好吃的一块肉。一千斤的牛身上可能也就只有一两斤的雪花牛肉。因为在脖子上所以它还叫脖仁脖仁肥瘦相间拥有大理石般的纹路涮4-6秒后入口口感柔嫩多脂十分鲜甜脆爽。"),
// new Food("匙柄",R.drawable.chibing,"\t\t\t\t匙柄位于牛前腿上方部位是牛肉中最好的部位之一即牛夹层里脊肉内层。匙柄的脂肪含量少切面呈树叶状且纹理清晰口感甜嫩无渣。"),
// new Food("匙仁",R.drawable.chiren,"\t\t\t\t匙仁在西餐牛肉的分割部位叫做“眼肉”该处肉质柔嫩且多汁有雪花纹滋味无穷。眼肉属于高档肉经过精细切割后外观呈四方圆弧状肉质红白镶嵌有大理石花斑状纹理。由于臀部的运动较多眼肉肉质细嫩脂肪及水分含量较高吃起来的口感比较香甜多汁、不干涩。"),
// new Food("三花趾",R.drawable.sanhuazhi,"\t\t\t\t如果你在吃潮汕牛肉火锅的时候雪花脖仁没有了怎么办虽然有点遗憾但还有很多部位一样美味三花趾就是其中的一种。这块牛肉的位置在上肢就是牛前腿的腱子肉牛肉中有较粗的筋。"),
// new Food("五花趾",R.drawable.wuhuazhi,"\t\t\t\t五花趾中的筋要比三花趾中的筋还要多一些肉的纹理也要更加的清晰一些在口感上也要更加的爽口吃起来非常的脆。如果你喜欢吃脆弹一些的肉那么潮汕牛肉火锅中的五花趾就是你的不二之选。"),
// new Food("肥胼",R.drawable.feipin,"\t\t\t\t肥胼对应的部位是大家再熟悉不过的牛腩位置并且是经过精修的牛腩只留牛腩腹心及上面一层牛油这样切开来之后每一片就有明显的两层一层嫩肉再带着一层黄色的牛油。口感肥腻细嫩对牛脂香味情有独钟的值得一试。"),
// new Food("吊龙",R.drawable.diaolong,"\t\t\t\t吊龙的意思是牛脊吊龙伴则是腰脊肉的两个侧边而这里头还要再细分吊龙伴中的两个小吊龙即牛骨盆的夹缝中两条长长的肉样子有点像龙虾的两根大触须潮汕人叫它“伴仔”或“龙虾须”这几两重的肉须便是吊龙伴中最为登峰造极的美味其特点是鲜甜而弹牙。"),
// new Food("嫩肉",R.drawable.nengrou,"\t\t\t\t嫩肉是在牛屁股上的肉基本上没有油脂全是精肉在潮汕牛肉火锅中算是产量比较大的一种了。嫩肉在潮汕牛肉火锅中最大的特点就是甜度高一些。 烫煮时间8秒 。"),
// new Food("胸口朥",R.drawable.xiongkoulao,"\t\t\t\t胸口朥是牛前胸的脂肪部分不是每一头牛都有这么一部分肉只有大而肥的牛才能长出十分稀有只有在潮汕火锅才能看到它的身影。它看上去油得出奇入口却是清甜间微微泛着牛油的香味口感脆而爽口、带点韧劲与“肥腻”两字完全不沾边。 烫煮时间30秒-3分钟 。"),
// };
// static public List<Product> initDatas() {
// List<Product> productsData = new ArrayList<Product>();
// Product product = new Product(0, "雪花",50, R.drawable.xuehua, 220, "潮汕牛肉", "牛运动最为频繁的一块活肉!", false);
// productsData.add(product);
// product = new Product(1, "匙柄",40, R.drawable.chibing, 340,"潮汕牛肉", "纹理清晰~口感甜嫩无渣!", false);
// productsData.add(product);
// product = new Product(2,"匙仁",52, R.drawable.chiren, 572, "潮汕牛肉", "肉质柔嫩且多汁~滋味无穷!", false);
// productsData.add(product);
// product = new Product(3,"三花趾",38, R.drawable.sanhuazhi, 678, "潮汕牛肉", "牛前腿的腱子肉~", false);
// productsData.add(product);
// product = new Product(4, "五花趾",38, R.drawable.wuhuazhi, 441, "潮汕牛肉", "纹理清晰~肉质爽口!", false);
// productsData.add(product);
// product = new Product(5,"肥胼",42, R.drawable.feipin, 233, "潮汕牛肉", "口感肥腻细嫩,富有牛脂香味~", false);
// productsData.add(product);
// product = new Product(6, "吊龙",40, R.drawable.diaolong, 128, "潮汕牛肉", "鲜甜弹牙~登峰造极的美味!", false);
// productsData.add(product);
// product = new Product(7, "嫩肉",36, R.drawable.nengrou, 214, "潮汕牛肉", "精肉无油~味道甜美!", false);
// productsData.add(product);
// product = new Product(8, "胸口朥",45, R.drawable.xiongkoulao, 82, "潮汕牛肉", "清甜间+牛油的香味~脆而爽口!", false);
// productsData.add(product);
// product = new Product(9, "牛肉丸",38, R.drawable.wanzi, 520, "潮汕牛肉", "纯肉打造!!不可错过!", false);
// productsData.add(product);
// return productsData;
// }
}

@ -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,375 @@
package franzliszt.foodturntable;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.sbw.atrue.Order.R;
public class Turntable extends SurfaceView implements SurfaceHolder.Callback, Runnable {
private SurfaceHolder mSurfaceHolder;
private Canvas mCanvas;
/**
* SurfaceView线
*/
private Thread mThread;
/**
* 线
*/
private boolean isRunning;
/**
* */
private String[] itemCharString;
/**
* */
private int[] itemImages;
private Bitmap[] mBitmaps;
/**
*
*/
private Bitmap mBgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.turntable_bgcolor );
/**
* */
private int[] itemColors;
/**
* */
private int mItemCount = 8;
/**
*
*/
private RectF mRange = new RectF();
/**
*
*/
private int mRadius;
/**
*
*/
private Paint mArcPaint;
/**
*
*/
private Paint mTextPaint;
/**
* */
private float mTextSize = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());
/**
*
*/
private double mSpeed = 0;
/**
*
*/
private int mCenter;
/**
* paddingpaddingLeft
*/
private int mPadding;
/**
* volatile线
*/
private volatile float mStartAngle = 0;
/**
*
*/
private boolean isShouldEnd = false;
/**
* 线sleep
* 线
*/
private long mOneTimeMinMillionSeconds = 50;
private int mDifferSpeed = 1;// 调用停止后递减的速度差值 要大于0
public Turntable(Context context) {
super(context);
init();
}
public Turntable(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Turntable(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public void InitNumber(int number){
if (number <= 0){
return;
}
/**
* */
if (number % 2 == 0){
InitArea(number);
}
}
private void InitArea(int number){
switch (number){
case 4:
fourParts();
break;
case 6:
sixParts();
break;
case 8:
eightParts();
break;
default:
sixParts();
}
}
private void fourParts(){
mItemCount = 4;
itemCharString = new String[]{"粉条", "面条", "米饭", "粥",};
itemImages = new int[]{R.drawable.fen, R.drawable.mian, R.drawable.rice, R.drawable.tang};
itemColors = new int[]{0xffffc300, 0xfff17e01, 0xffffc300, 0xfff17e01};
InitImage(mItemCount,itemImages);
}
private void sixParts(){
mItemCount = 6;
itemCharString = new String[]{"火锅", "汉堡", "巧克力", "奶茶", "蛋糕", "炸鸡"};
itemImages = new int[]{R.drawable.huoguo, R.drawable.hanbao, R.drawable.qiaokeli, R.drawable.naicha, R.drawable.dangao, R.drawable.zhaji1};
itemColors = new int[]{0xffffc300, 0xfff17e01, 0xffffc300, 0xfff17e01, 0xffffc300, 0xfff17e01};
InitImage(mItemCount,itemImages);
}
private void eightParts(){
mItemCount = 8;
itemCharString = new String[]{"苹果", "香蕉", "榴莲", "西瓜", "葡萄", "火龙果","芒果","草莓"};
itemImages = new int[]{R.drawable.apple, R.drawable.xaingjiao, R.drawable.liulian, R.drawable.xigua, R.drawable.putao, R.drawable.huolongguo,R.drawable.mangguo,R.drawable.caomei};
itemColors = new int[]{0xffffc300, 0xfff17e01, 0xffffc300, 0xfff17e01, 0xffffc300, 0xfff17e01,0xffffc300,0xfff17e01};
InitImage(mItemCount,itemImages);
}
private void init() {
mSurfaceHolder = this.getHolder();
// 管理SurfaceView的生命周期
mSurfaceHolder.addCallback(this);
// 能够获取焦点
this.setFocusable(true);
this.setFocusableInTouchMode(true);
// 保持常亮
this.setKeepScreenOn(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = Math.min(getMeasuredWidth(), getMeasuredHeight());
mPadding = getPaddingLeft();
mRadius = width - mPadding * 2;
// 中心点
mCenter = width / 2;
setMeasuredDimension(width, width);
}
private void InitImage(int count,int[] item){
mBitmaps = new Bitmap[mItemCount];
for (int i = 0; i < count; i++) {
mBitmaps[i] = BitmapFactory.decodeResource(getResources(), item[i]);
}
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
// 初始化盘块画笔
mArcPaint = new Paint();
mArcPaint.setAntiAlias(true);
mArcPaint.setDither(true);
// 初始化文字画笔
mTextPaint = new Paint();
mTextPaint.setColor(0xffffffff);
mTextPaint.setTextSize(mTextSize);
// 初始化盘块绘制范围
mRange = new RectF(mPadding, mPadding, mPadding + mRadius, mPadding + mRadius);
// 初始化图片
InitImage(mItemCount,itemImages);
isRunning = true;
mThread = new Thread(this);
mThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
isRunning = false;
}
@Override
public void run() {
/**
*
*/
while (isRunning) {
long preMillions = System.currentTimeMillis();
draw();
long afterMillions = System.currentTimeMillis();
long drawOnceTime = afterMillions - preMillions;
if (drawOnceTime < mOneTimeMinMillionSeconds) {
try {
Thread.sleep(mOneTimeMinMillionSeconds - drawOnceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void draw() {
try {
mCanvas = mSurfaceHolder.lockCanvas();
if (mCanvas != null) {
/* 绘制背景颜色*/
drawBgColor();
/*绘制区域*/
drawArea();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (mCanvas != null) {
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}
}
/**
*
*/
private void drawArea() {
// 起始角度
float tempAngle = mStartAngle;
// 每个盘块绘制的角度
float sweepAngele = 360 / mItemCount;
for (int i = 0; i < mItemCount; i++) {
mArcPaint.setColor(itemColors[i]);
// 绘制盘块
mCanvas.drawArc(mRange, tempAngle, sweepAngele, true, mArcPaint);
// 绘制文本
drawText(tempAngle, sweepAngele, itemCharString[i]);
// 绘制图标
drawIcon(tempAngle, mBitmaps[i]);
tempAngle += sweepAngele;
}
mStartAngle += mSpeed;
// 如果需要停止,让转速逐渐变小直到0
if (isShouldEnd) {
mSpeed -= mDifferSpeed;
}
if (mSpeed <= 0) {
mSpeed = 0;
isShouldEnd = false;
}
}
/**
*
*
* @param tempAngle
* @param bitmap
*/
private void drawIcon(float tempAngle, Bitmap bitmap) {
// 约束图片的宽度为直径的1/8,可以作为可变参数设置
int imgWidth = mRadius / 8;
// 获取弧度值
float angle = (float) ((tempAngle + 360 / mItemCount / 2) * Math.PI / 180);
// 约定图片位置在直径1/4处
int x = (int) (mCenter + mRadius / 4 * Math.cos(angle));
int y = (int) (mCenter + mRadius / 4 * Math.sin(angle));
// 确定图片位置
Rect rect = new Rect(x - imgWidth / 2, y - imgWidth / 2, x + imgWidth / 2, y + imgWidth / 2);
mCanvas.drawBitmap(bitmap, null, rect, null);
}
/**
*
*
* @param tempAngle
* @param sweepAngele
* @param itemTextStr
*/
private void drawText(float tempAngle, float sweepAngele, String itemTextStr) {
Path path = new Path();
path.addArc(mRange, tempAngle, sweepAngele);
// 利用水平偏移量让文字居中
float textWidth = mTextPaint.measureText(itemTextStr);
int hOffset = (int) (mRadius * Math.PI / mItemCount / 2 - textWidth / 2);
// 利用垂直偏移量让文字向圆心靠拢
int vOffset = mRadius / 2 / 6;
mCanvas.drawTextOnPath(itemTextStr, path, hOffset, vOffset, mTextPaint);
}
/**
*
*/
private void drawBgColor() {
mCanvas.drawColor(0xFFFFFFFF);
mCanvas.drawBitmap(mBgBitmap, null, new Rect(mPadding / 2, mPadding / 2, getMeasuredWidth() - mPadding / 2, getMeasuredWidth() - mPadding / 2), null);
}
/**
*
* index
*/
public void Start(int index) {
if (isStart()) {
return;
}
if (index < 0) {
mSpeed = 50 * (1 + Math.random() * (0.5));
isShouldEnd = false;
return;
}
}
/**
*
*/
public void Stop() {
if (isShouldEnd()) {
return;
}
// 将初始角度重置
mStartAngle = 0;
isShouldEnd = true;
}
/**
*
*
* @return
*/
public boolean isStart() {
return mSpeed != 0;
}
/**
* ()
*
* @return
*/
public boolean isShouldEnd() {
return isShouldEnd;
}
}

@ -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…
Cancel
Save