Android基础知识【项目实训-添加购物车】【8】

【该项目实训是Android基础知识的一个综合练习,特别提示:项目中会用到一些图片素材,都是随意整理的,稍后会上传一个资源,包含该事项项目的基本功能,也含有图片素材

【项目题目】:校园订餐App设计
综合案例
【目标】

当用户点击某一个 餐品时,会打开详细介绍界面,并可以确定购买数量,点击“预订”按钮就可以加入购物车。购物车中的每一项都对应  将来生成订单的 

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



    
    
    
    
    
    
	
	
	    
	    
	    
	
	
	

		

	    

	    
	    
	
	

3、食品详情界面效果

Android基础知识【项目实训-添加购物车】【8】_第1张图片

可以增加或减少 预订数量,也可以直接输入预订数量。

点击预订,可以加入购物车,并提示。

Android基础知识【项目实训-添加购物车】【8】_第2张图片

经 餐品加入购物车中,采用如下代码实现。

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、购物车的布局文件



    
    
    
        
	        
            
            
	        
            
            
        
        
        
             
            
            
        
        
        

6、购物车界面效果

Android基础知识【项目实训-添加购物车】【8】_第3张图片


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。



    
这个动画的播放,由触屏监听实现。施加触屏操作的代码 背景为 粉色。


你可能感兴趣的:(备忘,android)