【该项目实训是Android基础知识的一个综合练习,特别提示:项目中会用到一些图片素材,都是随意整理的,稍后会上传一个资源,包含该事项项目的基本功能,也含有图片素材】
当用户点击某一个 餐品时,会打开详细介绍界面,并可以确定购买数量,点击“预订”按钮就可以加入购物车。购物车中的每一项都对应 将来生成订单的
1、食品详情界面对应FoodDetailActivity 类,当点击食品列表中的某一项时,打开这个界面,并把对应的 食品对象通过Intent传过来。
下面这是传递所选食物对象的方法:
Intent intent =new Intent(this,FoodDetailActivity.class);
Bundle bd =new Bundle();
//Log.i("Msg", "当前点击列表"+lv + " "+lv.getId());
if(lv.getId()==R.id.promotionFoodList){
bd.putSerializable("food",pdata.get(index));
//Log.i("Msg", "当前选择:"+pdata.get(index).getFoodName());
}else if(lv.getId()==R.id.discountFoodList){
bd.putSerializable("food",ddata.get(index));
//Log.i("Msg", "当前选择:"+ddata.get(index).getFoodName());
}
intent.putExtras(bd);
startActivity(intent);
下面这是实现详情界面的代码:
public class FoodDetailActivity extends Activity {
FoodInfo food; //食物详情界面,展示的的食物对象
EditText num; //购物份数
Button buyBt; //购买按钮,
ImageButton addBt,subBt; //增加和减少 物品按钮
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_food_detail);
//
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setDisplayShowHomeEnabled(true);
//获取intent
Intent intent=getIntent();
food=(FoodInfo) intent.getSerializableExtra("food");
if(food==null){finish();}
init(food);
//
num=(EditText) findViewById(R.id.ac_fd_acount);
buyBt =(Button) findViewById(R.id.ac_fd_buyBt);
addBt =(ImageButton) findViewById(R.id.ac_fd_acount_add);
subBt =(ImageButton) findViewById(R.id.ac_fd_acount_sub);
addBt.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
String n=num.getText().toString();
num.setText(String.valueOf(Integer.parseInt(n)+1));
}}
);
subBt.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
String n=num.getText().toString();
int nn=Integer.parseInt(n)-1;
num.setText(String.valueOf(nn<1?1:nn));
}}
);
buyBt.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
String count=num.getText().toString();
if(count==null||count.trim().length()<1)return;
creatOrderItem(food,Integer.parseInt(count));
}}
);
//Log.i("Msg", food.toString());
}
/**
产生订单项对象
* @param food2 所订食物
* @param acount 数量
*/
protected void creatOrderItem(FoodInfo food2, int acount) {
//
Log.i("Msg", "产生订单项");
AccountItem item =new AccountItem();
//订单项所属订单,在用户提交订单时 生成。
item.setCount(acount);
item.setFood(food2);
item.setFoodId(food2.get_id());
EatApp app =(EatApp) getApplication();
app.orderItems.add(item);
Toast.makeText(this, "订购"+food.getFoodName()+"成功", Toast.LENGTH_LONG).show();
Log.i("Msg", "购车车中数据"+app.orderItems.size());
}
//根据传入的 食物对象,初始化本界面
private void init(FoodInfo food) {
ImageView iv=(ImageView) findViewById(R.id.ac_fd_img);
iv.setImageResource(Integer.parseInt( food.getImgId()));
TextView des=(TextView) findViewById(R.id.ac_fd_des);
des.setText(food.getDescription());
TextView name=(TextView) findViewById(R.id.ac_fd_name);
name.setText(food.getFoodName());
TextView price=(TextView) findViewById(R.id.ac_fd_price);
price.setText("¥ "+food.getPrice());
TextView tag1=(TextView) findViewById(R.id.ac_fd_tag1);
tag1.setText(food.getCategory());
TextView tag2=(TextView) findViewById(R.id.ac_fd_tag2);
tag2.setText(food.getType());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case android.R.id.home: //回退按钮点击
Intent intent =new Intent(this,MainActivity.class);
startActivity(intent);
finish();
break;
}
return super.onOptionsItemSelected(item);
}
}
2、食物详情界面布局文件,文件名是
activity_food_detail.xml
可以增加或减少 预订数量,也可以直接输入预订数量。
点击预订,可以加入购物车,并提示。
经 餐品加入购物车中,采用如下代码实现。
EatApp app =(EatApp) getApplication();
app.orderItems.add(item);实质上是将 购物的物品和数量组成 订单项对象,然后加入共享集合 区间。
4、当购物车非空时,点击购物车菜单,进入购物车详情界面。购物车界面对应ShopcartActivity.java。这个界面的功能也稍微有些复杂,因为它需要能更改 购物车中的数量和 删除某个项目。
/**
* @author Administrator
* 显示购物车中 详细信息界面
*/
public class ShopcartActivity extends Activity {
//统计费用
TextView yuanshi,peican,gongji;
//提交账单
Button submit;
//购物车货品列表
ListView shopList;
ShopcartListAdapter sla;
//ListView 项触屏时用
int x1,y1,x2,y2; //点下 和抬起时的坐标
//应用对象
EatApp app;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shopcart);
app=(EatApp) getApplication();
getActionBar().setDisplayHomeAsUpEnabled(true);
yuanshi=(TextView) findViewById(R.id.shopcart_total_yuanjia);
peican=(TextView) findViewById(R.id.shopcart_total_peisongfei);
gongji=(TextView) findViewById(R.id.shopcart_total_gongji);
submit=(Button) findViewById(R.id.shopcart_submit);
submit.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
//验证登录
if(app.userInfo==null){
Toast.makeText(ShopcartActivity.this, "请先登录", Toast.LENGTH_LONG).show();
//创建登录对话框
new LoginDialog(ShopcartActivity.this);
return;
}else{
Account a =createAccount();
if(a.get_id()==null){
Toast.makeText(ShopcartActivity.this,"订单创建失败",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(ShopcartActivity.this,"订单编号:"+a.get_id(),Toast.LENGTH_SHORT).show();
Log.i("Msg", "订单已经创建:"+a.toString());
//提交订单成功,返回主页或支付页面
Intent intent =new Intent(ShopcartActivity.this,PayActivity.class);
startActivity(intent);
ShopcartActivity.this.finish();
}
}
}}
);
//初始化购物列表
shopList =(ListView) findViewById(R.id.shopcart_listview);
initLv();
shopList.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent me) {
if(me.getAction()==MotionEvent.ACTION_DOWN){
x1=(int) me.getX();
y1=(int) me.getY();
}else if(me.getAction()==MotionEvent.ACTION_UP){
x2=(int) me.getX();
y2=(int) me.getY();
//点下和抬起时,对于的列表项
int p1=((ListView)v).pointToPosition(x1, y1);
int p2=((ListView)v).pointToPosition(x2, y2);
if(p1==p2&&x1-x2>20){
Log.i("Msg", "打算删除"+p1);
if(p1<0)return false;
removeItem(((ListView)v).getChildAt(p1),p1);
// app.orderItems.remove(p1); //移除数据
// initLv(); //重新初始化
// updateCheck(); //更新价格
}
}
return true;
}}
);
}
//产生订单
public Account createAccount(){
EatApp app =(EatApp) ShopcartActivity.this.getApplication();
Account a =new Account();
a.setState(0);
a.setUserId(app.userInfo.get_id());
a.setCreateDate(DateUtil.getCurrentDate());
//将订单插入数据库
EatDbHelper dbh=new EatDbHelper(this, "fooddb.db3", null, 1);
Account account =new AccountDao().createAccount(dbh,a);
//订单成功后,需要将订单项插入数据库
if(account.get_id()!=null){
int maxid =new AccountItemDao().insertAccountItem(dbh, account, app.orderItems);
if(maxid<1)account.set_id(null);
else{
//订单项及订单都插入成功,清空购物车
app.orderItems.clear();
}
Log.i("Msg", "订单项插入最大元素为:"+maxid);
}
return account;
}
//移除列表中的指定项,并播放动画
protected void removeItem(View itemView, final int pos) {
final Animation an=AnimationUtils.loadAnimation(this, R.anim.slidetoleft);
an.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation arg0) {
}
@Override
public void onAnimationRepeat(Animation arg0) {
}
@Override
public void onAnimationEnd(Animation arg0) {
app.orderItems.remove(pos); //移除数据
updateCheck();
sla.notifyDataSetChanged();
//an.cancel();
}
});
itemView.startAnimation(an);
}
//统计购物车中物品,计算总价
public void updateCheck() {
List items=app.orderItems;
float my=0;
for (AccountItem accountItem : items) {
my+=accountItem.getCount()*Float.parseFloat(accountItem.getFood().getPrice())*Float.parseFloat(accountItem.getFood().getDiscount());
}
my=Math.round(my*100/100);
yuanshi.setText("¥"+my);
float pc =0.00f;//配餐费在系统中并未 启用
peican.setText("¥"+String.valueOf(pc));
gongji.setText("¥"+String.valueOf(my+pc));
}
//初始化购物车列表
private void initLv() {
sla=new ShopcartListAdapter(
this,
app.orderItems,
R.layout.shopcartlist_item
);
shopList.setAdapter(sla);
updateCheck();//初始化列表数据后,计算账单
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case android.R.id.home: //回退按钮点击
Intent intent =new Intent(this,MainActivity.class);
startActivity(intent);
finish();
break;
}
return super.onOptionsItemSelected(item);
}
}
在购物车界面上要完成这样几个功能:
(0)检验是否登录,如果没有登录,打开登录对话框
(1)统计购物车中的物品,总计费用是多少
(2)当购物车中的物品数量改变事,重新计算 总价
(3)向左滑动某个项目时,可以删除掉它
(4)点击提交订单时,产生订单,更新数据库,同时将购物车中的订单项,补充所属订单属性,并跳转到支付界面
5、购物车的布局文件
7、初始化购物车列表的适配器是自定义的。
ShopcartListAdapter
代码如下:
public class ShopcartListAdapter extends BaseAdapter {
ShopcartActivity context;
List data;
int layout;
public ShopcartListAdapter(ShopcartActivity context, List data,
int layout) {
super();
this.context = context;
this.data = data;
this.layout = layout;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int arg0) {
return data.get(arg0);
}
@Override
public long getItemId(int arg0) {
return arg0;
}
@Override
public View getView(final int index, View view, ViewGroup group) {
View v=LayoutInflater.from(context).inflate(layout, null);
ImageView iv =(ImageView) v.findViewById(R.id.shopcartlist_item_img);
iv.setImageResource(Integer.parseInt(data.get(index).getFood().getImgId()));
TextView name=(TextView) v.findViewById(R.id.shopcartlist_item_name);
name.setText(data.get(index).getFood().getFoodName());
TextView price=(TextView) v.findViewById(R.id.shopcartlist_item_price);
price.setText("单价:¥"+data.get(index).getFood().getPrice());
float disc=Float.parseFloat(data.get(index).getFood().getDiscount());
if(disc<1){
TextView discount=(TextView) v.findViewById(R.id.shopcartlist_item_discount);
discount.setText("折扣:"+data.get(index).getFood().getDiscount());
}
final EditText count=(EditText) v.findViewById(R.id.shopcartlist_item_acount);
count.setText(String.valueOf(data.get(index).getCount()));
//监听 数量修改
ImageButton sub=(ImageButton) v.findViewById(R.id.shopcartlist_item_sub);
ImageButton add=(ImageButton) v.findViewById(R.id.shopcartlist_item_add);
sub.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
int n =Integer.parseInt(count.getText().toString());
n--;
if(n<1)n=1;
count.setText(String.valueOf(n));
data.get(index).setCount(n);
context.updateCheck();
}}
);
add.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
int n=Integer.parseInt(count.getText().toString())+1;
count.setText(String.valueOf(n));
data.get(index).setCount(n);
context.updateCheck();
}});
return v;
}
}
//监听 数量修改
ImageButton sub=(ImageButton) v.findViewById(R.id.shopcartlist_item_sub);
ImageButton add=(ImageButton) v.findViewById(R.id.shopcartlist_item_add);
8、购物车列表项的布局文件是shopcartlist_item。xml。
9、向左滑动某一列表,可以将其移除,此处用一个动画,采用属性动画文件完成。文件名是slidetoleft.xml。
这个动画的播放,由触屏监听实现。施加触屏操作的代码 背景为 粉色。