购物车的应用很广泛,电商app基本上都有它的身影。由于它用到了多种存储方式,通过项目对数据的存储有更高层次的了解。

1.设计思路

  首先看看购物车的外观。第一次进入时里面是空的,去购物页面加入购物车以后,返回到购物车才能看到商品列表。

      • 商品图表
      • 名称
      • 数量
      • 单价
      • 总价

  一般购物车图标出现在几乎所有的页面,或者某一个角落。

  一旦有新的商品加入购物车,购物车图标上的商品数量就加一。

  任何页面点击购物车图标直接进入购物车页面

  

  用到的存储方式:

    • 数据库SQLite:是最直观的数据库,购物车里的商品列表一定放在SQLite中,增删改查都少不了它。
    • 共享参数sharedpreferences:不同页面上的购物车图标都有数字,表示商品数量。因为每个页面都要显示,如果用sqlite每次都要查询的话,就会很费资源。又因为商品数量需要持久存储,所以也不合适放在全局内存,不然下次启动就会清空。
    • SD卡文件:通常电商app的图标都来自服务器端,又因为图片下载很耗流量,因此一次加载后面从SD卡中读取之前加载的内容,加载又快又不耗流量,一举两得。
    • 全局内存:上面说了,访问SD卡果然是个好主意,然而商品频道、购物车频道等可能在一个页面显示多张商品小图,如果每张小图都访问依次SD卡,频繁的SD卡访问读写是很耗资源的。更好的办法是把商品小图加载进全局内存,这样直接从内存中获取图片,高效又快速。之所以不把商品大图放入全局内存,是因为大图很耗空间,一不小心就会占用几十兆内存。

2.小知识

  菜单Menu

    1. 选项菜单------optionMenu

        通过按菜单键或点击事件触发

      2.上下文菜单----contextMenu

        通过长按事件触发

    都有对应的菜单布局文件,放在res/menu目录下。

  

  1.选项菜单------optionMenu

    弹出选项菜单的途径有3种:

      (1)按菜单键

      (2)在代码中手动打开,即调用openOptionMenu方法

      (3)按工具栏右侧的溢出菜单按钮

       需要重写两种方法:

      • onCreateOptionMenu:在页面打开时调用,需要指定菜单列表的XML文件。
      • onOptionItemSelected:在列表的菜单项被选中时调用,需要对不同的菜单项做分支处理
    •  <menu xmlns:android="http://schemas.android.com/apk/res/android" >
      
           <item
      android:id="@+id/menu_change_time"
      android:orderInCategory="1"
      android:title="改变时间"/> <item
      android:id="@+id/menu_change_color"
      android:orderInCategory="8"
      android:title="改变颜色"/> <item
      android:id="@+id/menu_change_bg"
      android:orderInCategory="9"
      android:title="改变背景"/> </menu>

    •  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:focusable="true"
      android:focusableInTouchMode="true"
      android:orientation="vertical"
      android:padding="10dp" > <Button
      android:id="@+id/btn_option"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="打开选项菜单,也可直接按菜单键"
      android:textColor="@color/black"
      android:textSize="17sp" /> <TextView
      android:id="@+id/tv_option"
      android:layout_width="match_parent"
      android:layout_height="50dp"
      android:gravity="left|center"
      android:textColor="@color/black"
      android:textSize="17sp" /> </LinearLayout>
       package com.example.alimjan.hello_world;
      
       /**
      * Created by alimjan on 7/13/2017.
      */ import com.example.alimjan.hello_world.Utils.DateUtil;
      import android.app.Activity;
      import android.content.Context;
      import android.content.Intent;
      import android.graphics.Color;
      import android.os.Bundle;
      import android.support.v7.app.AppCompatActivity;
      import android.util.Log;
      import android.view.Menu;
      import android.view.MenuItem;
      import android.view.View;
      import android.view.View.OnClickListener;
      import android.widget.TextView; public class class_4_5_2_1 extends Activity implements OnClickListener { private static final String TAG = "MenuOptionActivity";
      private TextView tv_option; @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.code_4_5_2_1);
      tv_option = (TextView) findViewById(R.id.tv_option);
      findViewById(R.id.btn_option).setOnClickListener(this); setRandomTime();
      } @Override
      public void onClick(View v) {
      if (v.getId() == R.id.btn_option) {
      //注意:如果当前页面继承自AppCompatActivity,并且appcompat版本不低于22.1.0
      //那么调用openOptionsMenu方法将不会弹出菜单。这应该是Android的一个bug
      openOptionsMenu();
      }
      } @Override
      public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.menu_option, menu);
      return true;
      } @Override
      public boolean onOptionsItemSelected(MenuItem item) {
      int id = item.getItemId();
      if (id == R.id.menu_change_time) {
      setRandomTime();
      } else if (id == R.id.menu_change_color) {
      tv_option.setTextColor(getRandomColor());
      } else if (id == R.id.menu_change_bg) {
      tv_option.setBackgroundColor(getRandomColor());
      }
      return true;
      } private void setRandomTime() {
      String desc = DateUtil.getCurDateStr("yyyy-MM-dd HH:mm:ss") + " 这里是菜单显示文本";
      tv_option.setText(desc);
      } private int[] mColorArray = {
      Color.BLACK, Color.WHITE, Color.RED, Color.YELLOW, Color.GREEN,
      Color.BLUE, Color.CYAN, Color.MAGENTA, Color.GRAY, Color.DKGRAY
      };
      private int getRandomColor() {
      int random = (int) (Math.random()*10 % 10);
      return mColorArray[random];
      }
      public static void startHome(Context mContext) {
      Intent intent = new Intent(mContext, class_4_5_2_1.class);
      mContext.startActivity(intent);
      } }

  2.上下文菜单----ContextMenu

    弹出上下文菜单的途径有两种:

      (1)默认在某个控件长按时弹出。

         通常在onStart方法中加入registerForContextMenu方法为指定控件注册上下文菜单,在onStop函数中加入unregisterForContextMenu方法为指定控件注销上下文                                    菜单

      (2)在长按事件之外的其他时间中打开上下文菜单,先执行registerForContextMenu方法注册菜单,然后执行openContextMenu方法打开菜单,最后执行                                      unregisterForContextMenu方法注销菜单。

    需要重写以下两种方法:

      • onCreateContextMenu:在此指定菜单列表的XML文件,作为上下文菜单列表项的来源。
      • onContextItemSelected:在此对不同的菜单项做分支处理。
    •  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:focusable="true"
      android:focusableInTouchMode="true"
      android:orientation="vertical"
      android:padding="10dp" > <Button
      android:id="@+id/btn_context"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="打开上下文菜单,长按下面文本亦可"
      android:textColor="@color/black"
      android:textSize="17sp" /> <TextView
      android:id="@+id/tv_context"
      android:layout_width="match_parent"
      android:layout_height="50dp"
      android:gravity="left|center"
      android:textColor="@color/black"
      android:textSize="17sp" /> </LinearLayout>
       package com.example.alimjan.hello_world;
      
       /**
      * Created by alimjan on 7/13/2017.
      */
      import com.example.alimjan.hello_world.Utils.DateUtil; import android.content.Context;
      import android.content.Intent;
      import android.graphics.Color;
      import android.os.Bundle;
      import android.support.v7.app.AppCompatActivity;
      import android.view.ContextMenu;
      import android.view.ContextMenu.ContextMenuInfo;
      import android.view.View.OnClickListener;
      import android.view.MenuItem;
      import android.view.View;
      import android.view.Window;
      import android.widget.TextView; public class class_4_5_2_2 extends AppCompatActivity implements OnClickListener { private TextView tv_context; @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.code_4_5_2_2);
      tv_context = (TextView) findViewById(R.id.tv_context);
      findViewById(R.id.btn_context).setOnClickListener(this); setRandomTime();
      } @Override
      public void onClick(View v) {
      if (v.getId() == R.id.btn_context) {
      registerForContextMenu(v);
      openContextMenu(v);
      unregisterForContextMenu(v);
      }
      } @Override
      protected void onResume() {
      registerForContextMenu(tv_context);
      super.onResume();
      } @Override
      protected void onPause() {
      unregisterForContextMenu(tv_context);
      super.onPause();
      } @Override
      public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
      getMenuInflater().inflate(R.menu.menu_option, menu);
      } @Override
      public boolean onContextItemSelected(MenuItem item) {
      int id = item.getItemId();
      if (id == R.id.menu_change_time) {
      setRandomTime();
      } else if (id == R.id.menu_change_color) {
      tv_context.setTextColor(getRandomColor());
      } else if (id == R.id.menu_change_bg) {
      tv_context.setBackgroundColor(getRandomColor());
      }
      return true;
      } private void setRandomTime() {
      String desc = DateUtil.getCurDateStr("yyyy-MM-dd HH:mm:ss") + " 这里是菜单显示文本";
      tv_context.setText(desc);
      } private int[] mColorArray = {
      Color.BLACK, Color.WHITE, Color.RED, Color.YELLOW, Color.GREEN,
      Color.BLUE, Color.CYAN, Color.MAGENTA, Color.GRAY, Color.DKGRAY
      };
      private int getRandomColor() {
      int random = (int) (Math.random()*10 % 10);
      return mColorArray[random];
      }
      public static void startHome(Context mContext) {
      Intent intent = new Intent(mContext, class_4_5_2_2.class);
      mContext.startActivity(intent);
      } }

      上下文菜单的菜单列表固定显示在页面中部,菜单外的其他区域颜色会变深。

3.开始敲代码

  步骤①  想好代码文件与布局文件的名称。(这里因为放到自己的笔记本上,文件名按照序号来起。)

     步骤②  在AndroidManiFest.xml文件中补充相应的配置。

     步骤③    敲业务逻辑以及布局文件的代码。

  

  下面贴代码:

shoppingcatractivity.java:

 package com.example.alimjan.hello_world;

 import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast; import com.example.alimjan.hello_world.Utils.FileUtil;
import com.example.alimjan.hello_world.bean.CartInfo;
import com.example.alimjan.hello_world.bean.GoodsInfo;
import com.example.alimjan.hello_world.dataBase.CartDBHelper;
import com.example.alimjan.hello_world.dataBase.GoodsDBHelper;
import com.example.alimjan.hello_world.Utils.DateUtil;
import com.example.alimjan.hello_world.Utils.SharedUtil; import java.util.ArrayList;
import java.util.HashMap; /**
* Created by alimjan on 2017/07/13.
*/
public class ShoppingCartActivity extends Activity implements OnClickListener { private final static String TAG = "ShoppingCartActivity";
private ImageView iv_menu;
private TextView tv_title;
private TextView tv_count;
private TextView tv_total_price;
private LinearLayout ll_content;
private LinearLayout ll_cart;
private LinearLayout ll_empty;
private int mCount; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_shopping_cart);
iv_menu = (ImageView) findViewById(R.id.iv_menu);
tv_title = (TextView) findViewById(R.id.tv_title);
tv_count = (TextView) findViewById(R.id.tv_count);
tv_total_price = (TextView) findViewById(R.id.tv_total_price);
ll_content = (LinearLayout) findViewById(R.id.ll_content);
ll_cart = (LinearLayout) findViewById(R.id.ll_cart);
ll_empty = (LinearLayout) findViewById(R.id.ll_empty); iv_menu.setOnClickListener(this);
findViewById(R.id.btn_shopping_channel).setOnClickListener(this);
findViewById(R.id.btn_settle).setOnClickListener(this);
iv_menu.setVisibility(View.VISIBLE);
tv_title.setText("购物车");
} //显示购物车图标中的商品数量
private void showCount(int count) {
mCount = count;
tv_count.setText(""+mCount);
if (mCount == 0) {
ll_content.setVisibility(View.GONE);
ll_cart.removeAllViews();
ll_empty.setVisibility(View.VISIBLE);
} else {
ll_content.setVisibility(View.VISIBLE);
ll_empty.setVisibility(View.GONE);
}
} @Override
public void onClick(View v) {
if (v.getId() == R.id.iv_menu) {
openOptionsMenu();
} else if (v.getId() == R.id.btn_shopping_channel) {
Intent intent = new Intent(this, ShoppingChannelActivity.class);
startActivity(intent);
} else if (v.getId() == R.id.btn_settle) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("结算商品");
builder.setMessage("客官抱歉,支付功能尚未开通,请下次再来");
builder.setPositiveButton("我知道了", null);
builder.create().show();
}
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_cart, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.menu_shopping) {
Intent intent = new Intent(this, ShoppingChannelActivity.class);
startActivity(intent);
} else if (id == R.id.menu_clear) {
//清空购物车数据库
mCartHelper.deleteAll();
ll_cart.removeAllViews();
SharedUtil.getIntance(this).writeShared("count", "0");
showCount(0);
mCartGoods.clear();
mGoodsMap.clear();
Toast.makeText(this, "购物车已清空", Toast.LENGTH_SHORT).show();
} else if (id == R.id.menu_return) {
finish();
}
return true;
} private HashMap<Integer, CartInfo> mCartGoods = new HashMap<Integer, CartInfo>();
private View mContextView;
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
mContextView = v;
getMenuInflater().inflate(R.menu.menu_goods, menu);
} @Override
public boolean onContextItemSelected(MenuItem item) {
CartInfo info = mCartGoods.get(mContextView.getId());
int id = item.getItemId();
if (id == R.id.menu_detail) {
//跳转到查看商品详情页面
goDetail(info.goods_id);
} else if (id == R.id.menu_delete) {
//从购物车删除商品的数据库操作
long goods_id = info.goods_id;
mCartHelper.delete("goods_id="+goods_id);
ll_cart.removeView(mContextView);
//更新购物车中的商品数量
int left_count = mCount-info.count;
for (int i=0; i<mCartArray.size(); i++) {
if (goods_id == mCartArray.get(i).goods_id) {
left_count = mCount-mCartArray.get(i).count;
mCartArray.remove(i);
break;
}
}
SharedUtil.getIntance(this).writeShared("count", ""+left_count);
showCount(left_count);
Toast.makeText(this, "已从购物车删除"+mGoodsMap.get(goods_id).name, Toast.LENGTH_SHORT).show();
mGoodsMap.remove(goods_id);
refreshTotalPrice();
}
return true;
} private void goDetail(long rowid) {
Intent intent = new Intent(this, ShoppingDetailActivity.class);
intent.putExtra("goods_id", rowid);
startActivity(intent);
} private GoodsDBHelper mGoodsHelper;
private CartDBHelper mCartHelper;
private String mFirst = "true"; @Override
protected void onResume() {
super.onResume();
mCount = Integer.parseInt(SharedUtil.getIntance(this).readShared("count", "0"));
showCount(mCount);
mGoodsHelper = GoodsDBHelper.getInstance(this, 1);
mGoodsHelper.openWriteLink();
mCartHelper = CartDBHelper.getInstance(this, 1);
mCartHelper.openWriteLink();
mFirst = SharedUtil.getIntance(this).readShared("first", "true");
downloadGoods();
SharedUtil.getIntance(this).writeShared("first", "false");
showCart();
} @Override
protected void onPause() {
super.onPause();
mGoodsHelper.closeLink();
mCartHelper.closeLink();
} private int mBeginViewId = 0x7F24FFF0;
private ArrayList<CartInfo> mCartArray = new ArrayList<CartInfo>();
private HashMap<Long, GoodsInfo> mGoodsMap = new HashMap<Long, GoodsInfo>();
private void showCart() {
mCartArray = mCartHelper.query("1=1");
Log.d(TAG, "mCartArray.size()="+mCartArray.size());
if (mCartArray==null || mCartArray.size()<=0) {
return;
}
ll_cart.removeAllViews();
LinearLayout ll_row = newLinearLayout(LinearLayout.HORIZONTAL, LayoutParams.WRAP_CONTENT);
ll_row.addView(newTextView(0, 2, Gravity.CENTER, "图片", Color.BLACK, 15));
ll_row.addView(newTextView(0, 3, Gravity.CENTER, "名称", Color.BLACK, 15));
ll_row.addView(newTextView(0, 1, Gravity.CENTER, "数量", Color.BLACK, 15));
ll_row.addView(newTextView(0, 1, Gravity.CENTER, "单价", Color.BLACK, 15));
ll_row.addView(newTextView(0, 1, Gravity.CENTER, "总价", Color.BLACK, 15));
ll_cart.addView(ll_row);
for (int i=0; i<mCartArray.size(); i++) {
final CartInfo info = mCartArray.get(i);
GoodsInfo goods = mGoodsHelper.queryById(info.goods_id);
Log.d(TAG, "name="+goods.name+",price="+goods.price+",desc="+goods.desc);
mGoodsMap.put(info.goods_id, goods);
ll_row = newLinearLayout(LinearLayout.HORIZONTAL, LayoutParams.WRAP_CONTENT);
ll_row.setId(mBeginViewId+i);
//添加商品小图
ImageView iv_thumb = new ImageView(this);
LinearLayout.LayoutParams iv_params = new LinearLayout.LayoutParams(
0, LayoutParams.WRAP_CONTENT, 2);
iv_thumb.setLayoutParams(iv_params);
iv_thumb.setScaleType(ScaleType.FIT_CENTER);
iv_thumb.setImageBitmap(MainApplication.getInstance().mIconMap.get(info.goods_id));
ll_row.addView(iv_thumb);
//添加商品名称与描述
LinearLayout ll_name = new LinearLayout(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
0, LayoutParams.MATCH_PARENT, 3);
ll_name.setLayoutParams(params);
ll_name.setOrientation(LinearLayout.VERTICAL);
ll_name.addView(newTextView(-3, 1, Gravity.LEFT, goods.name, Color.BLACK, 17));
ll_name.addView(newTextView(-3, 1, Gravity.LEFT, goods.desc, Color.GRAY, 12));
ll_row.addView(ll_name);
//添加商品数量、单价和总价
ll_row.addView(newTextView(1, 1, Gravity.CENTER, ""+info.count, Color.BLACK, 17));
ll_row.addView(newTextView(1, 1, Gravity.RIGHT, ""+(int)goods.price, Color.BLACK, 15));
ll_row.addView(newTextView(1, 1, Gravity.RIGHT, ""+(int)(info.count*goods.price), Color.RED, 17));
//给商品行添加点击事件
ll_row.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
goDetail(info.goods_id);
}
});
//给商品行注册上下文菜单
unregisterForContextMenu(ll_row);
registerForContextMenu(ll_row);
mCartGoods.put(ll_row.getId(), info);
ll_cart.addView(ll_row);
}
refreshTotalPrice();
} private void refreshTotalPrice() {
int total_price = 0;
for (CartInfo info : mCartArray) {
GoodsInfo goods = mGoodsMap.get(info.goods_id);
total_price += goods.price*info.count;
}
tv_total_price.setText(""+total_price);
} private LinearLayout newLinearLayout(int orientation, int height) {
LinearLayout ll_new = new LinearLayout(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, height);
//params.setMargins(2, 2, 2, 2);
ll_new.setLayoutParams(params);
ll_new.setOrientation(orientation);
ll_new.setBackgroundColor(Color.WHITE);
return ll_new;
} private TextView newTextView(int height, float weight, int gravity, String text, int textColor, int textSize) {
TextView tv_new = new TextView(this);
if (height == -3) { //垂直排列
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, 0, weight);
tv_new.setLayoutParams(params);
} else { //水平排列
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
0, (height==0)?LayoutParams.WRAP_CONTENT:LayoutParams.MATCH_PARENT, weight);
tv_new.setLayoutParams(params);
}
tv_new.setText(text);
tv_new.setTextColor(textColor);
tv_new.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
tv_new.setGravity(Gravity.CENTER|gravity);
return tv_new;
} private String[] mNameArray = {
"iphone7", "Mate8", "小米5", "vivo X6S", "OPPO R9plus", "魅族Pro6"
};
private String[] mDescArray = {
"Apple iPhone 7 128GB 玫瑰金色 移动联通电信4G手机",
"华为 HUAWEI Mate8 3GB+32GB版 移动联通4G手机(月光银)",
"小米手机5 全网通 高配版 3GB内存 64GB 白色",
"vivo X6S 金色 全网通4G 双卡双待 4GB+64GB",
"OPPO R9plus 4GB+64GB内存版 金色 全网通4G手机 双卡双待",
"魅族Pro6全网通公开版 4+32GB 银白色 移动联通电信4G手机 双卡双待"
};
private float[] mPriceArray = {5888, 2499, 1799, 2298, 2499, 2199};
private int[] mThumbArray = {
R.drawable.iphone_s, R.drawable.huawei_s, R.drawable.xiaomi_s,
R.drawable.vivo_s, R.drawable.oppo_9p_s, R.drawable.meizu_s
};
private int[] mPicArray = {
R.drawable.iphone, R.drawable.huawei, R.drawable.xiaomi,
R.drawable.vivo, R.drawable.oppo_9p, R.drawable.meizu
};
//模拟网络数据,初始化数据库中的商品信息
private void downloadGoods() {
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
if (mFirst.equals("true")) {
for (int i=0; i<mNameArray.length; i++) {
GoodsInfo info = new GoodsInfo();
info.name = mNameArray[i];
info.desc = mDescArray[i];
info.price = mPriceArray[i];
long rowid = mGoodsHelper.insert(info);
info.rowid = rowid;
//往全局内存写入商品小图
Bitmap thumb = BitmapFactory.decodeResource(getResources(), mThumbArray[i]);
MainApplication.getInstance().mIconMap.put(rowid, thumb);
String thumb_path = path + rowid + "_s.jpg";
FileUtil.saveImage(thumb_path, thumb);
info.thumb_path = thumb_path;
//往SD卡保存商品大图
Bitmap pic = BitmapFactory.decodeResource(getResources(), mPicArray[i]);
String pic_path = path + rowid + ".jpg";
FileUtil.saveImage(pic_path, pic);
pic.recycle();
info.pic_path = pic_path;
mGoodsHelper.update(info);
}
} else {
ArrayList<GoodsInfo> goodsArray = mGoodsHelper.query("1=1");
for (int i=0; i<goodsArray.size(); i++) {
GoodsInfo info = goodsArray.get(i);
Bitmap thumb = BitmapFactory.decodeFile(info.thumb_path);
MainApplication.getInstance().mIconMap.put(info.rowid, thumb);
}
}
} public static void startHome(Context mContext) {
Intent intent = new Intent(mContext, ShoppingCartActivity.class);
mContext.startActivity(intent);
} }
ShoppingChannelActivity:
 package com.example.alimjan.hello_world;

 import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import android.widget.Toast; import com.example.alimjan.hello_world.bean.CartInfo;
import com.example.alimjan.hello_world.bean.GoodsInfo;
import com.example.alimjan.hello_world.dataBase.CartDBHelper;
import com.example.alimjan.hello_world.dataBase.GoodsDBHelper;
import com.example.alimjan.hello_world.Utils.DateUtil;
import com.example.alimjan.hello_world.Utils.SharedUtil; import java.util.ArrayList; /**
* Created by alimjan on 2017/07/13.
*/
public class ShoppingChannelActivity extends AppCompatActivity implements OnClickListener { private final static String TAG = "ShoppingChannelActivity";
private TextView tv_title;
private TextView tv_count;
private LinearLayout ll_channel;
private int mCount; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shopping_channel);
tv_title = (TextView) findViewById(R.id.tv_title);
tv_count = (TextView) findViewById(R.id.tv_count);
ll_channel = (LinearLayout) findViewById(R.id.ll_channel);
findViewById(R.id.iv_cart).setOnClickListener(this);
tv_title.setText("手机商场");
} @Override
public void onClick(View v) {
if (v.getId() == R.id.iv_cart) {
Intent intent = new Intent(this, ShoppingCartActivity.class);
startActivity(intent);
}
} private void addToCart(long goods_id) {
mCount++;
tv_count.setText(""+mCount);
SharedUtil.getIntance(this).writeShared("count", ""+mCount);
CartInfo info = mCartHelper.queryByGoodsId(goods_id);
if (info != null) {
info.count++;
info.update_time = DateUtil.getCurDateStr("");
mCartHelper.update(info);
} else {
info = new CartInfo();
info.goods_id = goods_id;
info.count = 1;
info.update_time = DateUtil.getCurDateStr("");
mCartHelper.insert(info);
}
} private GoodsDBHelper mGoodsHelper;
private CartDBHelper mCartHelper; @Override
protected void onResume() {
super.onResume();
mCount = Integer.parseInt(SharedUtil.getIntance(this).readShared("count", "0"));
tv_count.setText(""+mCount);
mGoodsHelper = GoodsDBHelper.getInstance(this, 1);
mGoodsHelper.openReadLink();
mCartHelper = CartDBHelper.getInstance(this, 1);
mCartHelper.openWriteLink();
//展示商品列表
showGoods();
} @Override
protected void onPause() {
super.onPause();
mGoodsHelper.closeLink();
mCartHelper.closeLink();
} private LayoutParams mFullParams, mHalfParams;
private void showGoods() {
ll_channel.removeAllViews();
mFullParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
mHalfParams = new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1);
mHalfParams.setMargins(2, 2, 2, 2);
LinearLayout ll_row = newLinearLayout(LinearLayout.HORIZONTAL, 0);
ArrayList<GoodsInfo> goodsArray = mGoodsHelper.query("1=1");
int i=0;
for (; i<goodsArray.size(); i++) {
final GoodsInfo info = goodsArray.get(i);
LinearLayout ll_goods = newLinearLayout(LinearLayout.VERTICAL, 1);
ll_goods.setBackgroundColor(Color.WHITE);
//添加商品标题
TextView tv_name = new TextView(this);
tv_name.setLayoutParams(mFullParams);
tv_name.setGravity(Gravity.CENTER);
tv_name.setText(info.name);
tv_name.setTextColor(Color.BLACK);
tv_name.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17);
ll_goods.addView(tv_name);
//添加商品小图
ImageView iv_thumb = new ImageView(this);
iv_thumb.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT, 200));
iv_thumb.setScaleType(ScaleType.FIT_CENTER);
iv_thumb.setImageBitmap(MainApplication.getInstance().mIconMap.get(info.rowid));
iv_thumb.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(ShoppingChannelActivity.this, ShoppingDetailActivity.class);
intent.putExtra("goods_id", info.rowid);
startActivity(intent);
}
});
ll_goods.addView(iv_thumb);
//添加商品价格
LinearLayout ll_bottom = newLinearLayout(LinearLayout.HORIZONTAL, 0);
TextView tv_price = new TextView(this);
tv_price.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 2));
tv_price.setGravity(Gravity.CENTER);
tv_price.setText(""+(int)info.price);
tv_price.setTextColor(Color.RED);
tv_price.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
ll_bottom.addView(tv_price);
//添加购物车按钮
Button btn_add = new Button(this);
btn_add.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 3));
btn_add.setGravity(Gravity.CENTER);
btn_add.setText("加入购物车");
btn_add.setTextColor(Color.BLACK);
btn_add.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
btn_add.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
addToCart(info.rowid);
Toast.makeText(ShoppingChannelActivity.this,
"已添加一部"+info.name+"到购物车", Toast.LENGTH_SHORT).show();
}
});
ll_bottom.addView(btn_add);
ll_goods.addView(ll_bottom);
//添加商品项目
ll_row.addView(ll_goods);
if (i%2 == 1) {
ll_channel.addView(ll_row);
ll_row = newLinearLayout(LinearLayout.HORIZONTAL, 0);
}
}
if (i%2 == 0) {
ll_row.addView(newLinearLayout(LinearLayout.VERTICAL, 1));
ll_channel.addView(ll_row);
}
} private LinearLayout newLinearLayout(int orientation, int weight) {
LinearLayout ll_new = new LinearLayout(this);
ll_new.setLayoutParams((weight==0)?mFullParams:mHalfParams);
ll_new.setOrientation(orientation);
return ll_new;
} }
ShoppingDetailActivity:
 package com.example.alimjan.hello_world;

 import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast; import com.example.alimjan.hello_world.bean.CartInfo;
import com.example.alimjan.hello_world.bean.GoodsInfo;
import com.example.alimjan.hello_world.dataBase.CartDBHelper;
import com.example.alimjan.hello_world.dataBase.GoodsDBHelper;
import com.example.alimjan.hello_world.Utils.DateUtil;
import com.example.alimjan.hello_world.Utils.SharedUtil; /**
* Created by alimjan on 2017/07/13.
*/
public class ShoppingDetailActivity extends AppCompatActivity implements OnClickListener { private TextView tv_title;
private TextView tv_count;
private TextView tv_goods_price;
private TextView tv_goods_desc;
private ImageView iv_goods_pic;
private int mCount;
private long mGoodsId; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shopping_detail);
tv_title = (TextView) findViewById(R.id.tv_title);
tv_count = (TextView) findViewById(R.id.tv_count);
tv_goods_price = (TextView) findViewById(R.id.tv_goods_price);
tv_goods_desc = (TextView) findViewById(R.id.tv_goods_desc);
iv_goods_pic = (ImageView) findViewById(R.id.iv_goods_pic);
findViewById(R.id.iv_cart).setOnClickListener(this);
findViewById(R.id.btn_add_cart).setOnClickListener(this); mCount = Integer.parseInt(SharedUtil.getIntance(this).readShared("count", "0"));
tv_count.setText(""+mCount);
} @Override
public void onClick(View v) {
if (v.getId() == R.id.iv_cart) {
Intent intent = new Intent(this, ShoppingCartActivity.class);
startActivity(intent);
} else if (v.getId() == R.id.btn_add_cart) {
//添加购物车数据库
addToCart(mGoodsId);
Toast.makeText(this, "成功添加至购物车", Toast.LENGTH_SHORT).show();
}
} private void addToCart(long goods_id) {
mCount++;
tv_count.setText(""+mCount);
SharedUtil.getIntance(this).writeShared("count", ""+mCount);
CartInfo info = mCartHelper.queryByGoodsId(goods_id);
if (info != null) {
info.count++;
info.update_time = DateUtil.getCurDateStr("");
mCartHelper.update(info);
} else {
info = new CartInfo();
info.goods_id = goods_id;
info.count = 1;
info.update_time = DateUtil.getCurDateStr("");
mCartHelper.insert(info);
}
} private GoodsDBHelper mGoodsHelper;
private CartDBHelper mCartHelper; @Override
protected void onResume() {
super.onResume();
mGoodsHelper = GoodsDBHelper.getInstance(this, 1);
mGoodsHelper.openReadLink();
mCartHelper = CartDBHelper.getInstance(this, 1);
mCartHelper.openWriteLink();
//展示商品信息
showDetail();
} @Override
protected void onPause() {
super.onPause();
mGoodsHelper.closeLink();
mCartHelper.closeLink();
} private void showDetail() {
mGoodsId = getIntent().getLongExtra("goods_id", 0l);
if (mGoodsId > 0) {
GoodsInfo info = mGoodsHelper.queryById(mGoodsId);
tv_title.setText(info.name);
tv_goods_desc.setText(info.desc);
tv_goods_price.setText(""+info.price);
Bitmap pic = BitmapFactory.decodeFile(info.pic_path);
iv_goods_pic.setImageBitmap(pic);
}
} }
activity_shopping_cart.xml
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffdd"
android:orientation="vertical" > <include layout="@layout/activity_shopping_title" /> <ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content" > <FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp" > <LinearLayout
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone" > <LinearLayout
android:id="@+id/ll_cart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp" > <TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center|right"
android:text="总金额:"
android:textColor="@color/black"
android:textSize="17sp" /> <TextView
android:id="@+id/tv_total_price"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="center|left"
android:textColor="@color/red"
android:textSize="25sp" /> <Button
android:id="@+id/btn_settle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="结算"
android:textColor="@color/black"
android:textSize="20sp" />
</LinearLayout> </LinearLayout> <LinearLayout
android:id="@+id/ll_empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone" > <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="100dp"
android:layout_marginTop="100dp"
android:gravity="center"
android:text="哎呀,购物车空空如也,快去选购商品吧"
android:textColor="@color/black"
android:textSize="17sp" /> <Button
android:id="@+id/btn_shopping_channel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="逛逛手机商场"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout>
</FrameLayout>
</ScrollView> </LinearLayout>
activity_shopping_channel.xml
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffdd"
android:orientation="vertical" > <include layout="@layout/activity_shopping_title" /> <ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content" > <LinearLayout
android:id="@+id/ll_channel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="vertical" >
</LinearLayout>
</ScrollView> </LinearLayout>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffdd"
android:orientation="vertical" > <include layout="@layout/activity_shopping_title" /> <ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="vertical" > <ImageView
android:id="@+id/iv_goods_pic"
android:layout_width="match_parent"
android:layout_height="400dp"
android:scaleType="fitCenter" /> <TextView
android:id="@+id/tv_goods_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/red"
android:textSize="22sp" /> <TextView
android:id="@+id/tv_goods_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="15sp" /> <Button
android:id="@+id/btn_add_cart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="加入购物车"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout>
</ScrollView> </LinearLayout>

  一些工具类:

 package com.example.alimjan.hello_world.Utils;

 import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Locale; public class FileUtil { public static void saveText(String path, String txt) {
try {
FileOutputStream fos = new FileOutputStream(path);
fos.write(txt.getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
} public static String openText(String path) {
String readStr = "";
try {
FileInputStream fis = new FileInputStream(path);
byte[] b = new byte[fis.available()];
fis.read(b);
readStr = new String(b);
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
return readStr;
} public static void saveImage(String path, Bitmap bitmap) {
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path));
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
bos.flush();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
} public static Bitmap openImage(String path) {
Bitmap bitmap = null;
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
bitmap = BitmapFactory.decodeStream(bis);
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
} public static ArrayList<File> getFileList(String path, String[] extendArray) {
ArrayList<File> displayedContent = new ArrayList<File>();
File[] files = null;
File directory = new File(path);
if (extendArray != null && extendArray.length>0) {
FilenameFilter fileFilter = getTypeFilter(extendArray);
files = directory.listFiles(fileFilter);
} else {
files = directory.listFiles();
} if (files != null) {
for (File f : files) {
if (!f.isDirectory() && !f.isHidden()) {
displayedContent.add(f);
}
}
}
return displayedContent;
} public static FilenameFilter getTypeFilter(String[] extendArray) {
final ArrayList<String> fileExtensions = new ArrayList<String>();
for (int i=0; i<extendArray.length; i++) {
fileExtensions.add(extendArray[i]);
}
FilenameFilter fileNameFilter = new FilenameFilter() {
@Override
public boolean accept(File directory, String fileName) {
boolean matched = false;
File f = new File(String.format("%s/%s",
directory.getAbsolutePath(), fileName));
matched = f.isDirectory();
if (!matched) {
for (String s : fileExtensions) {
s = String.format(".{0,}\\%s$", s);
s = s.toUpperCase(Locale.getDefault());
fileName = fileName.toUpperCase(Locale.getDefault());
matched = fileName.matches(s);
if (matched) {
break;
}
}
}
return matched;
}
};
return fileNameFilter;
} }
 package com.example.alimjan.hello_world.dataBase;

 import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log; import com.example.alimjan.hello_world.bean.GoodsInfo; import java.util.ArrayList; public class GoodsDBHelper extends SQLiteOpenHelper {
private static final String TAG = "GoodsDBHelper";
private static final String DB_NAME = "goods.db";
private static final int DB_VERSION = 1;
private static GoodsDBHelper mHelper = null;
private SQLiteDatabase mDB = null;
private static final String TABLE_NAME = "goods_info"; private GoodsDBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
} private GoodsDBHelper(Context context, int version) {
super(context, DB_NAME, null, version);
} public static GoodsDBHelper getInstance(Context context, int version) {
if (version > 0 && mHelper == null) {
mHelper = new GoodsDBHelper(context, version);
} else if (mHelper == null) {
mHelper = new GoodsDBHelper(context);
}
return mHelper;
} public SQLiteDatabase openReadLink() {
if (mDB == null || mDB.isOpen() != true) {
mDB = mHelper.getReadableDatabase();
}
return mDB;
} public SQLiteDatabase openWriteLink() {
if (mDB == null || mDB.isOpen() != true) {
mDB = mHelper.getWritableDatabase();
}
return mDB;
} public void closeLink() {
if (mDB != null && mDB.isOpen() == true) {
mDB.close();
mDB = null;
}
} public String getDBName() {
if (mHelper != null) {
return mHelper.getDatabaseName();
} else {
return DB_NAME;
}
} @Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "onCreate");
String drop_sql = "DROP TABLE IF EXISTS " + TABLE_NAME + ";";
Log.d(TAG, "drop_sql:" + drop_sql);
db.execSQL(drop_sql);
String create_sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " ("
+ "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ "name VARCHAR NOT NULL," + "desc VARCHAR NOT NULL,"
+ "price FLOAT NOT NULL," + "thumb_path VARCHAR NOT NULL,"
+ "pic_path VARCHAR NOT NULL"
+ ");";
Log.d(TAG, "create_sql:" + create_sql);
db.execSQL(create_sql);
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
} public int delete(String condition) {
int count = mDB.delete(TABLE_NAME, condition, null);
return count;
} public int deleteAll() {
int count = mDB.delete(TABLE_NAME, "1=1", null);
return count;
} public long insert(GoodsInfo info) {
ArrayList<GoodsInfo> infoArray = new ArrayList<GoodsInfo>();
infoArray.add(info);
return insert(infoArray);
} public long insert(ArrayList<GoodsInfo> infoArray) {
long result = -1;
for (int i = 0; i < infoArray.size(); i++) {
GoodsInfo info = infoArray.get(i);
// 如果存在相同rowid的记录,则更新记录
if (info.rowid > 0) {
String condition = String.format("rowid='%d'", info.rowid);
update(info, condition);
result = info.rowid;
continue;
}
// 不存在唯一性重复的记录,则插入新记录
ContentValues cv = new ContentValues();
cv.put("name", info.name);
cv.put("desc", info.desc);
cv.put("price", info.price);
cv.put("thumb_path", info.thumb_path);
cv.put("pic_path", info.pic_path);
result = mDB.insert(TABLE_NAME, "", cv);
// 添加成功后返回行号,失败后返回-1
if (result == -1) {
return result;
}
}
return result;
} public int update(GoodsInfo info, String condition) {
ContentValues cv = new ContentValues();
cv.put("name", info.name);
cv.put("desc", info.desc);
cv.put("price", info.price);
cv.put("thumb_path", info.thumb_path);
cv.put("pic_path", info.pic_path);
int count = mDB.update(TABLE_NAME, cv, condition, null);
return count;
} public int update(GoodsInfo info) {
return update(info, "rowid="+info.rowid);
} public ArrayList<GoodsInfo> query(String condition) {
String sql = String.format("select rowid,_id,name,desc,price,thumb_path,pic_path" +
" from %s where %s;", TABLE_NAME, condition);
Log.d(TAG, "query sql: "+sql);
ArrayList<GoodsInfo> infoArray = new ArrayList<GoodsInfo>();
Cursor cursor = mDB.rawQuery(sql, null);
if (cursor.moveToFirst()) {
for (;; cursor.moveToNext()) {
GoodsInfo info = new GoodsInfo();
info.rowid = cursor.getLong(0);
info.xuhao = cursor.getInt(1);
info.name = cursor.getString(2);
info.desc = cursor.getString(3);
info.price = cursor.getFloat(4);
info.thumb_path = cursor.getString(5);
info.pic_path = cursor.getString(6);
infoArray.add(info);
if (cursor.isLast() == true) {
break;
}
}
}
cursor.close();
return infoArray;
} public GoodsInfo queryById(long rowid) {
GoodsInfo info = null;
ArrayList<GoodsInfo> infoArray = query(String.format("rowid='%d'", rowid));
if (infoArray.size() > 0) {
info = infoArray.get(0);
}
return info;
} }
 package com.example.alimjan.hello_world.dataBase;

 import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log; import com.example.alimjan.hello_world.bean.CartInfo; import java.util.ArrayList; public class CartDBHelper extends SQLiteOpenHelper {
private static final String TAG = "CartDBHelper";
private static final String DB_NAME = "cart.db";
private static final int DB_VERSION = 1;
private static CartDBHelper mHelper = null;
private SQLiteDatabase mDB = null;
private static final String TABLE_NAME = "cart_info"; private CartDBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
} private CartDBHelper(Context context, int version) {
super(context, DB_NAME, null, version);
} public static CartDBHelper getInstance(Context context, int version) {
if (version > 0 && mHelper == null) {
mHelper = new CartDBHelper(context, version);
} else if (mHelper == null) {
mHelper = new CartDBHelper(context);
}
return mHelper;
} public SQLiteDatabase openReadLink() {
if (mDB == null || mDB.isOpen() != true) {
mDB = mHelper.getReadableDatabase();
}
return mDB;
} public SQLiteDatabase openWriteLink() {
if (mDB == null || mDB.isOpen() != true) {
mDB = mHelper.getWritableDatabase();
}
return mDB;
} public void closeLink() {
if (mDB != null && mDB.isOpen() == true) {
mDB.close();
mDB = null;
}
} public String getDBName() {
if (mHelper != null) {
return mHelper.getDatabaseName();
} else {
return DB_NAME;
}
} @Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "onCreate");
String drop_sql = "DROP TABLE IF EXISTS " + TABLE_NAME + ";";
Log.d(TAG, "drop_sql:" + drop_sql);
db.execSQL(drop_sql);
String create_sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " ("
+ "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ "goods_id LONG NOT NULL," + "count INTEGER NOT NULL,"
+ "update_time VARCHAR NOT NULL"
+ ");";
Log.d(TAG, "create_sql:" + create_sql);
db.execSQL(create_sql);
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
} public int delete(String condition) {
int count = mDB.delete(TABLE_NAME, condition, null);
return count;
} public int deleteAll() {
int count = mDB.delete(TABLE_NAME, "1=1", null);
return count;
} public long insert(CartInfo info) {
ArrayList<CartInfo> infoArray = new ArrayList<CartInfo>();
infoArray.add(info);
return insert(infoArray);
} public long insert(ArrayList<CartInfo> infoArray) {
long result = -1;
for (int i = 0; i < infoArray.size(); i++) {
CartInfo info = infoArray.get(i);
Log.d(TAG, "goods_id="+info.goods_id+", count="+info.count);
// 如果存在相同rowid的记录,则更新记录
if (info.rowid > 0) {
String condition = String.format("rowid='%d'", info.rowid);
update(info, condition);
result = info.rowid;
continue;
}
// 不存在唯一性重复的记录,则插入新记录
ContentValues cv = new ContentValues();
cv.put("goods_id", info.goods_id);
cv.put("count", info.count);
cv.put("update_time", info.update_time);
result = mDB.insert(TABLE_NAME, "", cv);
// 添加成功后返回行号,失败后返回-1
if (result == -1) {
return result;
}
}
return result;
} public int update(CartInfo info, String condition) {
ContentValues cv = new ContentValues();
cv.put("goods_id", info.goods_id);
cv.put("count", info.count);
cv.put("update_time", info.update_time);
int count = mDB.update(TABLE_NAME, cv, condition, null);
return count;
} public int update(CartInfo info) {
return update(info, "rowid="+info.rowid);
} public ArrayList<CartInfo> query(String condition) {
String sql = String.format("select rowid,_id,goods_id,count,update_time" +
" from %s where %s;", TABLE_NAME, condition);
Log.d(TAG, "query sql: "+sql);
ArrayList<CartInfo> infoArray = new ArrayList<CartInfo>();
Cursor cursor = mDB.rawQuery(sql, null);
if (cursor.moveToFirst()) {
for (;; cursor.moveToNext()) {
CartInfo info = new CartInfo();
info.rowid = cursor.getLong(0);
info.xuhao = cursor.getInt(1);
info.goods_id = cursor.getLong(2);
info.count = cursor.getInt(3);
info.update_time = cursor.getString(4);
infoArray.add(info);
if (cursor.isLast() == true) {
break;
}
}
}
cursor.close();
return infoArray;
} public CartInfo queryById(long rowid) {
CartInfo info = null;
ArrayList<CartInfo> infoArray = query(String.format("rowid='%d'", rowid));
if (infoArray.size() > 0) {
info = infoArray.get(0);
}
return info;
} public CartInfo queryByGoodsId(long goods_id) {
CartInfo info = null;
ArrayList<CartInfo> infoArray = query(String.format("goods_id='%d'", goods_id));
if (infoArray.size() > 0) {
info = infoArray.get(0);
}
return info;
} }
 package com.example.alimjan.hello_world.bean;

 public class GoodsInfo {
public long rowid;
public int xuhao;
public String name;
public String desc;
public float price;
public String thumb_path;
public String pic_path; public GoodsInfo() {
rowid = 0l;
xuhao = 0;
name = "";
desc = "";
price = 0;
thumb_path = "";
pic_path = "";
}
}
 package com.example.alimjan.hello_world.bean;

 public class CartInfo {
public long rowid;
public int xuhao;
public long goods_id;
public int count;
public String update_time; public CartInfo() {
rowid = 0l;
xuhao = 0;
goods_id = 0l;
count = 0;
update_time = "";
}
}
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
android:id="@+id/menu_shopping"
android:orderInCategory="1"
android:title="去商场购物"/> <item
android:id="@+id/menu_clear"
android:orderInCategory="2"
android:title="清空购物车"/> <item
android:id="@+id/menu_return"
android:orderInCategory="9"
android:title="返回"/> </menu>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
android:id="@+id/menu_detail"
android:orderInCategory="1"
android:title="查看商品详情"/> <item
android:id="@+id/menu_delete"
android:orderInCategory="2"
android:title="从购物车删除"/> </menu>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" > <solid android:color="#ff6666" /> </shape>

到此也就完成的差不多了,一些工具类放在下面了。

Android 开发笔记___实战项目:购物车的更多相关文章

  1. Android 开发笔记___初级控件之实战__计算器

    功能简单,实现并不难,对于初学者可以总和了解初级控件的基本使用. 用到的知识点如下: 线性布局 LinearLayout:整体界面是从上往下的,因此需要垂直方向的linearlayout:下面每行四个 ...

  2. Android 开发笔记___基本适配器的使用__BaseAdapter

    之前用到过ArryAdapter适用于纯文本的列表数据,SimpleAdapter适用于带图标的列表数据,但在实际应用中常常有更复杂的列表,比如同一项中存在多个控件,这时候用前面的两个会比较复杂,而且 ...

  3. Android 开发笔记___时间选择器---timePicker

    像datepicker一样,也有timepicker. 同样有timepickerdialog 所用到的方法还是一样,监听时间选择器的变化. package com.example.alimjan.h ...

  4. Android 开发笔记___存储方式__共享参数__sharedprefences

    Android 的数据存储方式有四种,这次是[共享参数__sharedprefences] 听起来挺别扭的,平时看到的app里面,当用户删除了一些软件以后下次安装,发现原来的设置还在,这种情况就是把一 ...

  5. Android 开发笔记___登陆app

    package com.example.alimjan.hello_world; /** * Created by alimjan on 7/4/2017. */ import android.con ...

  6. Android 开发笔记___复选框__checkbox

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout ...

  7. Android 开发笔记___图像按钮__imageButton

    IMAGEBUTTON 其实派生自image view,而不是派生自button.,image view拥有的属性和方法,image button 统统拥有,只是imagebutton有个默认的按钮外 ...

  8. Android 开发笔记___滚动视图__scroll view

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  9. Android 开发笔记___图像视图__简单截屏

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

随机推荐

  1. 云计算之openstack ocata 项目搭建详细方法

    之前写过一篇<openstack mitaka 配置详解>然而最近使用发现阿里不再提供m版本的源,所以最近又开始学习ocata版本,并进行总结,写下如下文档 OpenStack ocata ...

  2. 怎样使用自定义标签简化 js、css 引入?

    国庆将至,工作兴致全无,来总结点项目里平时不起眼干货. 前端引入 js .css 一般是这样: <script type="text/javascript" src=&quo ...

  3. Bmob云IM实现头像更换并存入Bmob云数据库中(1.拍照替换,2.相册选择)

    看图效果如下: 1.个人资料界面 2.点击头像弹出对话框 3.点击拍照 4.切割图片,选择合适的部分 5.点击保存,头像替换完毕,下面看从相册中选择图片. 6.点击相册 7.任选一张图片 8.切割图片 ...

  4. 分享基于分布式Http长连接框架--架构模型

    我画了个简单的架构图来帮助说明: 其实为发布订阅架构模式. 生产者和消费者我们统一可理解为客户端,消息中间件可认为是服务端. 生产者和消费者做为客户端要跟服务端交互,则先通过代理订阅服务端,订阅成功后 ...

  5. js自执行函数写法

    (1)写法1 (function(){ //函数内容 })() (2)写法2 (function(){ //函数内容 }())

  6. 手把手教你用npm发布一个包,详细教程

    我们已经实现了路由的自动化构建,但是我们可以看到,一大串代码怼在里面.当然你也可以说,把它封装在一个JS文件里面,然后使用require('./autoRoute.js')给引入进来,那也行.但是,为 ...

  7. LCT学习笔记

    最近自学了一下LCT(Link-Cut-Tree),参考了Saramanda及Yang_Zhe等众多大神的论文博客,对LCT有了一个初步的认识,LCT是一种动态树,可以处理动态问题的算法.对于树分治中 ...

  8. Ubuntu 14.04 安装 Sublime Text 3

    1. 实验环境 Ubuntu 14.04 + Sublime text 3 2. sublime text介绍 ublime Text 是一款流行的文本编辑器软件,有点类似于TextMate,跨平台, ...

  9. 自动化selenium开发

    一.开发环境搭建 1.Firefox浏览器 1.1 下载firefix并安装. 1.2 Firefox中打开"开始菜单“ -> ”开发者“ -> ”获取更多工具“ -> 搜 ...

  10. wpf 画刷的分类

    System.Windows.Media.Brush最上一层画刷 System.Windows.Media.GradientBrush  线性画刷 ,下层主要有两种画刷 System.Windows. ...