购物车的应用很广泛,电商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:在列表的菜单项被选中时调用,需要对不同的菜单项做分支处理
      1. <menu xmlns:android="http://schemas.android.com/apk/res/android" >
      2.  
      3. <item
      4. android:id="@+id/menu_change_time"
      5. android:orderInCategory="1"
      6. android:title="改变时间"/>
      7.  
      8. <item
      9. android:id="@+id/menu_change_color"
      10. android:orderInCategory="8"
      11. android:title="改变颜色"/>
      12.  
      13. <item
      14. android:id="@+id/menu_change_bg"
      15. android:orderInCategory="9"
      16. android:title="改变背景"/>
      17.  
      18. </menu>

      1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      2. android:layout_width="match_parent"
      3. android:layout_height="match_parent"
      4. android:focusable="true"
      5. android:focusableInTouchMode="true"
      6. android:orientation="vertical"
      7. android:padding="10dp" >
      8.  
      9. <Button
      10. android:id="@+id/btn_option"
      11. android:layout_width="match_parent"
      12. android:layout_height="wrap_content"
      13. android:text="打开选项菜单,也可直接按菜单键"
      14. android:textColor="@color/black"
      15. android:textSize="17sp" />
      16.  
      17. <TextView
      18. android:id="@+id/tv_option"
      19. android:layout_width="match_parent"
      20. android:layout_height="50dp"
      21. android:gravity="left|center"
      22. android:textColor="@color/black"
      23. android:textSize="17sp" />
      24.  
      25. </LinearLayout>
      1. package com.example.alimjan.hello_world;
      2.  
      3. /**
      4. * Created by alimjan on 7/13/2017.
      5. */
      6.  
      7. import com.example.alimjan.hello_world.Utils.DateUtil;
      8. import android.app.Activity;
      9. import android.content.Context;
      10. import android.content.Intent;
      11. import android.graphics.Color;
      12. import android.os.Bundle;
      13. import android.support.v7.app.AppCompatActivity;
      14. import android.util.Log;
      15. import android.view.Menu;
      16. import android.view.MenuItem;
      17. import android.view.View;
      18. import android.view.View.OnClickListener;
      19. import android.widget.TextView;
      20.  
      21. public class class_4_5_2_1 extends Activity implements OnClickListener {
      22.  
      23. private static final String TAG = "MenuOptionActivity";
      24. private TextView tv_option;
      25.  
      26. @Override
      27. protected void onCreate(Bundle savedInstanceState) {
      28. super.onCreate(savedInstanceState);
      29. setContentView(R.layout.code_4_5_2_1);
      30. tv_option = (TextView) findViewById(R.id.tv_option);
      31. findViewById(R.id.btn_option).setOnClickListener(this);
      32.  
      33. setRandomTime();
      34. }
      35.  
      36. @Override
      37. public void onClick(View v) {
      38. if (v.getId() == R.id.btn_option) {
      39. //注意:如果当前页面继承自AppCompatActivity,并且appcompat版本不低于22.1.0
      40. //那么调用openOptionsMenu方法将不会弹出菜单。这应该是Android的一个bug
      41. openOptionsMenu();
      42. }
      43. }
      44.  
      45. @Override
      46. public boolean onCreateOptionsMenu(Menu menu) {
      47. getMenuInflater().inflate(R.menu.menu_option, menu);
      48. return true;
      49. }
      50.  
      51. @Override
      52. public boolean onOptionsItemSelected(MenuItem item) {
      53. int id = item.getItemId();
      54. if (id == R.id.menu_change_time) {
      55. setRandomTime();
      56. } else if (id == R.id.menu_change_color) {
      57. tv_option.setTextColor(getRandomColor());
      58. } else if (id == R.id.menu_change_bg) {
      59. tv_option.setBackgroundColor(getRandomColor());
      60. }
      61. return true;
      62. }
      63.  
      64. private void setRandomTime() {
      65. String desc = DateUtil.getCurDateStr("yyyy-MM-dd HH:mm:ss") + " 这里是菜单显示文本";
      66. tv_option.setText(desc);
      67. }
      68.  
      69. private int[] mColorArray = {
      70. Color.BLACK, Color.WHITE, Color.RED, Color.YELLOW, Color.GREEN,
      71. Color.BLUE, Color.CYAN, Color.MAGENTA, Color.GRAY, Color.DKGRAY
      72. };
      73. private int getRandomColor() {
      74. int random = (int) (Math.random()*10 % 10);
      75. return mColorArray[random];
      76. }
      77. public static void startHome(Context mContext) {
      78. Intent intent = new Intent(mContext, class_4_5_2_1.class);
      79. mContext.startActivity(intent);
      80. }
      81.  
      82. }

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

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

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

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

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

    需要重写以下两种方法:

      • onCreateContextMenu:在此指定菜单列表的XML文件,作为上下文菜单列表项的来源。
      • onContextItemSelected:在此对不同的菜单项做分支处理。
      1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      2. android:layout_width="match_parent"
      3. android:layout_height="match_parent"
      4. android:focusable="true"
      5. android:focusableInTouchMode="true"
      6. android:orientation="vertical"
      7. android:padding="10dp" >
      8.  
      9. <Button
      10. android:id="@+id/btn_context"
      11. android:layout_width="match_parent"
      12. android:layout_height="wrap_content"
      13. android:text="打开上下文菜单,长按下面文本亦可"
      14. android:textColor="@color/black"
      15. android:textSize="17sp" />
      16.  
      17. <TextView
      18. android:id="@+id/tv_context"
      19. android:layout_width="match_parent"
      20. android:layout_height="50dp"
      21. android:gravity="left|center"
      22. android:textColor="@color/black"
      23. android:textSize="17sp" />
      24.  
      25. </LinearLayout>
      1. package com.example.alimjan.hello_world;
      2.  
      3. /**
      4. * Created by alimjan on 7/13/2017.
      5. */
      6. import com.example.alimjan.hello_world.Utils.DateUtil;
      7.  
      8. import android.content.Context;
      9. import android.content.Intent;
      10. import android.graphics.Color;
      11. import android.os.Bundle;
      12. import android.support.v7.app.AppCompatActivity;
      13. import android.view.ContextMenu;
      14. import android.view.ContextMenu.ContextMenuInfo;
      15. import android.view.View.OnClickListener;
      16. import android.view.MenuItem;
      17. import android.view.View;
      18. import android.view.Window;
      19. import android.widget.TextView;
      20.  
      21. public class class_4_5_2_2 extends AppCompatActivity implements OnClickListener {
      22.  
      23. private TextView tv_context;
      24.  
      25. @Override
      26. protected void onCreate(Bundle savedInstanceState) {
      27. super.onCreate(savedInstanceState);
      28. setContentView(R.layout.code_4_5_2_2);
      29. tv_context = (TextView) findViewById(R.id.tv_context);
      30. findViewById(R.id.btn_context).setOnClickListener(this);
      31.  
      32. setRandomTime();
      33. }
      34.  
      35. @Override
      36. public void onClick(View v) {
      37. if (v.getId() == R.id.btn_context) {
      38. registerForContextMenu(v);
      39. openContextMenu(v);
      40. unregisterForContextMenu(v);
      41. }
      42. }
      43.  
      44. @Override
      45. protected void onResume() {
      46. registerForContextMenu(tv_context);
      47. super.onResume();
      48. }
      49.  
      50. @Override
      51. protected void onPause() {
      52. unregisterForContextMenu(tv_context);
      53. super.onPause();
      54. }
      55.  
      56. @Override
      57. public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
      58. getMenuInflater().inflate(R.menu.menu_option, menu);
      59. }
      60.  
      61. @Override
      62. public boolean onContextItemSelected(MenuItem item) {
      63. int id = item.getItemId();
      64. if (id == R.id.menu_change_time) {
      65. setRandomTime();
      66. } else if (id == R.id.menu_change_color) {
      67. tv_context.setTextColor(getRandomColor());
      68. } else if (id == R.id.menu_change_bg) {
      69. tv_context.setBackgroundColor(getRandomColor());
      70. }
      71. return true;
      72. }
      73.  
      74. private void setRandomTime() {
      75. String desc = DateUtil.getCurDateStr("yyyy-MM-dd HH:mm:ss") + " 这里是菜单显示文本";
      76. tv_context.setText(desc);
      77. }
      78.  
      79. private int[] mColorArray = {
      80. Color.BLACK, Color.WHITE, Color.RED, Color.YELLOW, Color.GREEN,
      81. Color.BLUE, Color.CYAN, Color.MAGENTA, Color.GRAY, Color.DKGRAY
      82. };
      83. private int getRandomColor() {
      84. int random = (int) (Math.random()*10 % 10);
      85. return mColorArray[random];
      86. }
      87. public static void startHome(Context mContext) {
      88. Intent intent = new Intent(mContext, class_4_5_2_2.class);
      89. mContext.startActivity(intent);
      90. }
      91.  
      92. }

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

3.开始敲代码

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

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

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

  

  下面贴代码:

shoppingcatractivity.java:

  1. package com.example.alimjan.hello_world;
  2.  
  3. import android.app.Activity;
  4. import android.app.AlertDialog;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.graphics.Bitmap;
  8. import android.graphics.BitmapFactory;
  9. import android.graphics.Color;
  10. import android.os.Bundle;
  11. import android.os.Environment;
  12. import android.util.Log;
  13. import android.util.TypedValue;
  14. import android.view.ContextMenu;
  15. import android.view.ContextMenu.ContextMenuInfo;
  16. import android.view.Gravity;
  17. import android.view.Menu;
  18. import android.view.MenuItem;
  19. import android.view.View;
  20. import android.view.View.OnClickListener;
  21. import android.view.ViewGroup.LayoutParams;
  22. import android.view.Window;
  23. import android.widget.ImageView;
  24. import android.widget.ImageView.ScaleType;
  25. import android.widget.LinearLayout;
  26. import android.widget.TextView;
  27. import android.widget.Toast;
  28.  
  29. import com.example.alimjan.hello_world.Utils.FileUtil;
  30. import com.example.alimjan.hello_world.bean.CartInfo;
  31. import com.example.alimjan.hello_world.bean.GoodsInfo;
  32. import com.example.alimjan.hello_world.dataBase.CartDBHelper;
  33. import com.example.alimjan.hello_world.dataBase.GoodsDBHelper;
  34. import com.example.alimjan.hello_world.Utils.DateUtil;
  35. import com.example.alimjan.hello_world.Utils.SharedUtil;
  36.  
  37. import java.util.ArrayList;
  38. import java.util.HashMap;
  39.  
  40. /**
  41. * Created by alimjan on 2017/07/13.
  42. */
  43. public class ShoppingCartActivity extends Activity implements OnClickListener {
  44.  
  45. private final static String TAG = "ShoppingCartActivity";
  46. private ImageView iv_menu;
  47. private TextView tv_title;
  48. private TextView tv_count;
  49. private TextView tv_total_price;
  50. private LinearLayout ll_content;
  51. private LinearLayout ll_cart;
  52. private LinearLayout ll_empty;
  53. private int mCount;
  54.  
  55. @Override
  56. protected void onCreate(Bundle savedInstanceState) {
  57. super.onCreate(savedInstanceState);
  58. requestWindowFeature(Window.FEATURE_NO_TITLE);
  59. setContentView(R.layout.activity_shopping_cart);
  60. iv_menu = (ImageView) findViewById(R.id.iv_menu);
  61. tv_title = (TextView) findViewById(R.id.tv_title);
  62. tv_count = (TextView) findViewById(R.id.tv_count);
  63. tv_total_price = (TextView) findViewById(R.id.tv_total_price);
  64. ll_content = (LinearLayout) findViewById(R.id.ll_content);
  65. ll_cart = (LinearLayout) findViewById(R.id.ll_cart);
  66. ll_empty = (LinearLayout) findViewById(R.id.ll_empty);
  67.  
  68. iv_menu.setOnClickListener(this);
  69. findViewById(R.id.btn_shopping_channel).setOnClickListener(this);
  70. findViewById(R.id.btn_settle).setOnClickListener(this);
  71. iv_menu.setVisibility(View.VISIBLE);
  72. tv_title.setText("购物车");
  73. }
  74.  
  75. //显示购物车图标中的商品数量
  76. private void showCount(int count) {
  77. mCount = count;
  78. tv_count.setText(""+mCount);
  79. if (mCount == 0) {
  80. ll_content.setVisibility(View.GONE);
  81. ll_cart.removeAllViews();
  82. ll_empty.setVisibility(View.VISIBLE);
  83. } else {
  84. ll_content.setVisibility(View.VISIBLE);
  85. ll_empty.setVisibility(View.GONE);
  86. }
  87. }
  88.  
  89. @Override
  90. public void onClick(View v) {
  91. if (v.getId() == R.id.iv_menu) {
  92. openOptionsMenu();
  93. } else if (v.getId() == R.id.btn_shopping_channel) {
  94. Intent intent = new Intent(this, ShoppingChannelActivity.class);
  95. startActivity(intent);
  96. } else if (v.getId() == R.id.btn_settle) {
  97. AlertDialog.Builder builder = new AlertDialog.Builder(this);
  98. builder.setTitle("结算商品");
  99. builder.setMessage("客官抱歉,支付功能尚未开通,请下次再来");
  100. builder.setPositiveButton("我知道了", null);
  101. builder.create().show();
  102. }
  103. }
  104.  
  105. @Override
  106. public boolean onCreateOptionsMenu(Menu menu) {
  107. getMenuInflater().inflate(R.menu.menu_cart, menu);
  108. return true;
  109. }
  110.  
  111. @Override
  112. public boolean onOptionsItemSelected(MenuItem item) {
  113. int id = item.getItemId();
  114. if (id == R.id.menu_shopping) {
  115. Intent intent = new Intent(this, ShoppingChannelActivity.class);
  116. startActivity(intent);
  117. } else if (id == R.id.menu_clear) {
  118. //清空购物车数据库
  119. mCartHelper.deleteAll();
  120. ll_cart.removeAllViews();
  121. SharedUtil.getIntance(this).writeShared("count", "0");
  122. showCount(0);
  123. mCartGoods.clear();
  124. mGoodsMap.clear();
  125. Toast.makeText(this, "购物车已清空", Toast.LENGTH_SHORT).show();
  126. } else if (id == R.id.menu_return) {
  127. finish();
  128. }
  129. return true;
  130. }
  131.  
  132. private HashMap<Integer, CartInfo> mCartGoods = new HashMap<Integer, CartInfo>();
  133. private View mContextView;
  134. @Override
  135. public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
  136. mContextView = v;
  137. getMenuInflater().inflate(R.menu.menu_goods, menu);
  138. }
  139.  
  140. @Override
  141. public boolean onContextItemSelected(MenuItem item) {
  142. CartInfo info = mCartGoods.get(mContextView.getId());
  143. int id = item.getItemId();
  144. if (id == R.id.menu_detail) {
  145. //跳转到查看商品详情页面
  146. goDetail(info.goods_id);
  147. } else if (id == R.id.menu_delete) {
  148. //从购物车删除商品的数据库操作
  149. long goods_id = info.goods_id;
  150. mCartHelper.delete("goods_id="+goods_id);
  151. ll_cart.removeView(mContextView);
  152. //更新购物车中的商品数量
  153. int left_count = mCount-info.count;
  154. for (int i=0; i<mCartArray.size(); i++) {
  155. if (goods_id == mCartArray.get(i).goods_id) {
  156. left_count = mCount-mCartArray.get(i).count;
  157. mCartArray.remove(i);
  158. break;
  159. }
  160. }
  161. SharedUtil.getIntance(this).writeShared("count", ""+left_count);
  162. showCount(left_count);
  163. Toast.makeText(this, "已从购物车删除"+mGoodsMap.get(goods_id).name, Toast.LENGTH_SHORT).show();
  164. mGoodsMap.remove(goods_id);
  165. refreshTotalPrice();
  166. }
  167. return true;
  168. }
  169.  
  170. private void goDetail(long rowid) {
  171. Intent intent = new Intent(this, ShoppingDetailActivity.class);
  172. intent.putExtra("goods_id", rowid);
  173. startActivity(intent);
  174. }
  175.  
  176. private GoodsDBHelper mGoodsHelper;
  177. private CartDBHelper mCartHelper;
  178. private String mFirst = "true";
  179.  
  180. @Override
  181. protected void onResume() {
  182. super.onResume();
  183. mCount = Integer.parseInt(SharedUtil.getIntance(this).readShared("count", "0"));
  184. showCount(mCount);
  185. mGoodsHelper = GoodsDBHelper.getInstance(this, 1);
  186. mGoodsHelper.openWriteLink();
  187. mCartHelper = CartDBHelper.getInstance(this, 1);
  188. mCartHelper.openWriteLink();
  189. mFirst = SharedUtil.getIntance(this).readShared("first", "true");
  190. downloadGoods();
  191. SharedUtil.getIntance(this).writeShared("first", "false");
  192. showCart();
  193. }
  194.  
  195. @Override
  196. protected void onPause() {
  197. super.onPause();
  198. mGoodsHelper.closeLink();
  199. mCartHelper.closeLink();
  200. }
  201.  
  202. private int mBeginViewId = 0x7F24FFF0;
  203. private ArrayList<CartInfo> mCartArray = new ArrayList<CartInfo>();
  204. private HashMap<Long, GoodsInfo> mGoodsMap = new HashMap<Long, GoodsInfo>();
  205. private void showCart() {
  206. mCartArray = mCartHelper.query("1=1");
  207. Log.d(TAG, "mCartArray.size()="+mCartArray.size());
  208. if (mCartArray==null || mCartArray.size()<=0) {
  209. return;
  210. }
  211. ll_cart.removeAllViews();
  212. LinearLayout ll_row = newLinearLayout(LinearLayout.HORIZONTAL, LayoutParams.WRAP_CONTENT);
  213. ll_row.addView(newTextView(0, 2, Gravity.CENTER, "图片", Color.BLACK, 15));
  214. ll_row.addView(newTextView(0, 3, Gravity.CENTER, "名称", Color.BLACK, 15));
  215. ll_row.addView(newTextView(0, 1, Gravity.CENTER, "数量", Color.BLACK, 15));
  216. ll_row.addView(newTextView(0, 1, Gravity.CENTER, "单价", Color.BLACK, 15));
  217. ll_row.addView(newTextView(0, 1, Gravity.CENTER, "总价", Color.BLACK, 15));
  218. ll_cart.addView(ll_row);
  219. for (int i=0; i<mCartArray.size(); i++) {
  220. final CartInfo info = mCartArray.get(i);
  221. GoodsInfo goods = mGoodsHelper.queryById(info.goods_id);
  222. Log.d(TAG, "name="+goods.name+",price="+goods.price+",desc="+goods.desc);
  223. mGoodsMap.put(info.goods_id, goods);
  224. ll_row = newLinearLayout(LinearLayout.HORIZONTAL, LayoutParams.WRAP_CONTENT);
  225. ll_row.setId(mBeginViewId+i);
  226. //添加商品小图
  227. ImageView iv_thumb = new ImageView(this);
  228. LinearLayout.LayoutParams iv_params = new LinearLayout.LayoutParams(
  229. 0, LayoutParams.WRAP_CONTENT, 2);
  230. iv_thumb.setLayoutParams(iv_params);
  231. iv_thumb.setScaleType(ScaleType.FIT_CENTER);
  232. iv_thumb.setImageBitmap(MainApplication.getInstance().mIconMap.get(info.goods_id));
  233. ll_row.addView(iv_thumb);
  234. //添加商品名称与描述
  235. LinearLayout ll_name = new LinearLayout(this);
  236. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
  237. 0, LayoutParams.MATCH_PARENT, 3);
  238. ll_name.setLayoutParams(params);
  239. ll_name.setOrientation(LinearLayout.VERTICAL);
  240. ll_name.addView(newTextView(-3, 1, Gravity.LEFT, goods.name, Color.BLACK, 17));
  241. ll_name.addView(newTextView(-3, 1, Gravity.LEFT, goods.desc, Color.GRAY, 12));
  242. ll_row.addView(ll_name);
  243. //添加商品数量、单价和总价
  244. ll_row.addView(newTextView(1, 1, Gravity.CENTER, ""+info.count, Color.BLACK, 17));
  245. ll_row.addView(newTextView(1, 1, Gravity.RIGHT, ""+(int)goods.price, Color.BLACK, 15));
  246. ll_row.addView(newTextView(1, 1, Gravity.RIGHT, ""+(int)(info.count*goods.price), Color.RED, 17));
  247. //给商品行添加点击事件
  248. ll_row.setOnClickListener(new OnClickListener() {
  249. @Override
  250. public void onClick(View v) {
  251. goDetail(info.goods_id);
  252. }
  253. });
  254. //给商品行注册上下文菜单
  255. unregisterForContextMenu(ll_row);
  256. registerForContextMenu(ll_row);
  257. mCartGoods.put(ll_row.getId(), info);
  258. ll_cart.addView(ll_row);
  259. }
  260. refreshTotalPrice();
  261. }
  262.  
  263. private void refreshTotalPrice() {
  264. int total_price = 0;
  265. for (CartInfo info : mCartArray) {
  266. GoodsInfo goods = mGoodsMap.get(info.goods_id);
  267. total_price += goods.price*info.count;
  268. }
  269. tv_total_price.setText(""+total_price);
  270. }
  271.  
  272. private LinearLayout newLinearLayout(int orientation, int height) {
  273. LinearLayout ll_new = new LinearLayout(this);
  274. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
  275. LayoutParams.MATCH_PARENT, height);
  276. //params.setMargins(2, 2, 2, 2);
  277. ll_new.setLayoutParams(params);
  278. ll_new.setOrientation(orientation);
  279. ll_new.setBackgroundColor(Color.WHITE);
  280. return ll_new;
  281. }
  282.  
  283. private TextView newTextView(int height, float weight, int gravity, String text, int textColor, int textSize) {
  284. TextView tv_new = new TextView(this);
  285. if (height == -3) { //垂直排列
  286. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
  287. LayoutParams.MATCH_PARENT, 0, weight);
  288. tv_new.setLayoutParams(params);
  289. } else { //水平排列
  290. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
  291. 0, (height==0)?LayoutParams.WRAP_CONTENT:LayoutParams.MATCH_PARENT, weight);
  292. tv_new.setLayoutParams(params);
  293. }
  294. tv_new.setText(text);
  295. tv_new.setTextColor(textColor);
  296. tv_new.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
  297. tv_new.setGravity(Gravity.CENTER|gravity);
  298. return tv_new;
  299. }
  300.  
  301. private String[] mNameArray = {
  302. "iphone7", "Mate8", "小米5", "vivo X6S", "OPPO R9plus", "魅族Pro6"
  303. };
  304. private String[] mDescArray = {
  305. "Apple iPhone 7 128GB 玫瑰金色 移动联通电信4G手机",
  306. "华为 HUAWEI Mate8 3GB+32GB版 移动联通4G手机(月光银)",
  307. "小米手机5 全网通 高配版 3GB内存 64GB 白色",
  308. "vivo X6S 金色 全网通4G 双卡双待 4GB+64GB",
  309. "OPPO R9plus 4GB+64GB内存版 金色 全网通4G手机 双卡双待",
  310. "魅族Pro6全网通公开版 4+32GB 银白色 移动联通电信4G手机 双卡双待"
  311. };
  312. private float[] mPriceArray = {5888, 2499, 1799, 2298, 2499, 2199};
  313. private int[] mThumbArray = {
  314. R.drawable.iphone_s, R.drawable.huawei_s, R.drawable.xiaomi_s,
  315. R.drawable.vivo_s, R.drawable.oppo_9p_s, R.drawable.meizu_s
  316. };
  317. private int[] mPicArray = {
  318. R.drawable.iphone, R.drawable.huawei, R.drawable.xiaomi,
  319. R.drawable.vivo, R.drawable.oppo_9p, R.drawable.meizu
  320. };
  321. //模拟网络数据,初始化数据库中的商品信息
  322. private void downloadGoods() {
  323. String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
  324. if (mFirst.equals("true")) {
  325. for (int i=0; i<mNameArray.length; i++) {
  326. GoodsInfo info = new GoodsInfo();
  327. info.name = mNameArray[i];
  328. info.desc = mDescArray[i];
  329. info.price = mPriceArray[i];
  330. long rowid = mGoodsHelper.insert(info);
  331. info.rowid = rowid;
  332. //往全局内存写入商品小图
  333. Bitmap thumb = BitmapFactory.decodeResource(getResources(), mThumbArray[i]);
  334. MainApplication.getInstance().mIconMap.put(rowid, thumb);
  335. String thumb_path = path + rowid + "_s.jpg";
  336. FileUtil.saveImage(thumb_path, thumb);
  337. info.thumb_path = thumb_path;
  338. //往SD卡保存商品大图
  339. Bitmap pic = BitmapFactory.decodeResource(getResources(), mPicArray[i]);
  340. String pic_path = path + rowid + ".jpg";
  341. FileUtil.saveImage(pic_path, pic);
  342. pic.recycle();
  343. info.pic_path = pic_path;
  344. mGoodsHelper.update(info);
  345. }
  346. } else {
  347. ArrayList<GoodsInfo> goodsArray = mGoodsHelper.query("1=1");
  348. for (int i=0; i<goodsArray.size(); i++) {
  349. GoodsInfo info = goodsArray.get(i);
  350. Bitmap thumb = BitmapFactory.decodeFile(info.thumb_path);
  351. MainApplication.getInstance().mIconMap.put(info.rowid, thumb);
  352. }
  353. }
  354. }
  355.  
  356. public static void startHome(Context mContext) {
  357. Intent intent = new Intent(mContext, ShoppingCartActivity.class);
  358. mContext.startActivity(intent);
  359. }
  360.  
  361. }
  1. ShoppingChannelActivity:
  1. package com.example.alimjan.hello_world;
  2.  
  3. import android.content.Intent;
  4. import android.graphics.Color;
  5. import android.os.Bundle;
  6. import android.support.v7.app.AppCompatActivity;
  7. import android.util.TypedValue;
  8. import android.view.Gravity;
  9. import android.view.View;
  10. import android.view.View.OnClickListener;
  11. import android.widget.Button;
  12. import android.widget.ImageView;
  13. import android.widget.ImageView.ScaleType;
  14. import android.widget.LinearLayout;
  15. import android.widget.LinearLayout.LayoutParams;
  16. import android.widget.TextView;
  17. import android.widget.Toast;
  18.  
  19. import com.example.alimjan.hello_world.bean.CartInfo;
  20. import com.example.alimjan.hello_world.bean.GoodsInfo;
  21. import com.example.alimjan.hello_world.dataBase.CartDBHelper;
  22. import com.example.alimjan.hello_world.dataBase.GoodsDBHelper;
  23. import com.example.alimjan.hello_world.Utils.DateUtil;
  24. import com.example.alimjan.hello_world.Utils.SharedUtil;
  25.  
  26. import java.util.ArrayList;
  27.  
  28. /**
  29. * Created by alimjan on 2017/07/13.
  30. */
  31. public class ShoppingChannelActivity extends AppCompatActivity implements OnClickListener {
  32.  
  33. private final static String TAG = "ShoppingChannelActivity";
  34. private TextView tv_title;
  35. private TextView tv_count;
  36. private LinearLayout ll_channel;
  37. private int mCount;
  38.  
  39. @Override
  40. protected void onCreate(Bundle savedInstanceState) {
  41. super.onCreate(savedInstanceState);
  42. setContentView(R.layout.activity_shopping_channel);
  43. tv_title = (TextView) findViewById(R.id.tv_title);
  44. tv_count = (TextView) findViewById(R.id.tv_count);
  45. ll_channel = (LinearLayout) findViewById(R.id.ll_channel);
  46. findViewById(R.id.iv_cart).setOnClickListener(this);
  47. tv_title.setText("手机商场");
  48. }
  49.  
  50. @Override
  51. public void onClick(View v) {
  52. if (v.getId() == R.id.iv_cart) {
  53. Intent intent = new Intent(this, ShoppingCartActivity.class);
  54. startActivity(intent);
  55. }
  56. }
  57.  
  58. private void addToCart(long goods_id) {
  59. mCount++;
  60. tv_count.setText(""+mCount);
  61. SharedUtil.getIntance(this).writeShared("count", ""+mCount);
  62. CartInfo info = mCartHelper.queryByGoodsId(goods_id);
  63. if (info != null) {
  64. info.count++;
  65. info.update_time = DateUtil.getCurDateStr("");
  66. mCartHelper.update(info);
  67. } else {
  68. info = new CartInfo();
  69. info.goods_id = goods_id;
  70. info.count = 1;
  71. info.update_time = DateUtil.getCurDateStr("");
  72. mCartHelper.insert(info);
  73. }
  74. }
  75.  
  76. private GoodsDBHelper mGoodsHelper;
  77. private CartDBHelper mCartHelper;
  78.  
  79. @Override
  80. protected void onResume() {
  81. super.onResume();
  82. mCount = Integer.parseInt(SharedUtil.getIntance(this).readShared("count", "0"));
  83. tv_count.setText(""+mCount);
  84. mGoodsHelper = GoodsDBHelper.getInstance(this, 1);
  85. mGoodsHelper.openReadLink();
  86. mCartHelper = CartDBHelper.getInstance(this, 1);
  87. mCartHelper.openWriteLink();
  88. //展示商品列表
  89. showGoods();
  90. }
  91.  
  92. @Override
  93. protected void onPause() {
  94. super.onPause();
  95. mGoodsHelper.closeLink();
  96. mCartHelper.closeLink();
  97. }
  98.  
  99. private LayoutParams mFullParams, mHalfParams;
  100. private void showGoods() {
  101. ll_channel.removeAllViews();
  102. mFullParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
  103. mHalfParams = new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1);
  104. mHalfParams.setMargins(2, 2, 2, 2);
  105. LinearLayout ll_row = newLinearLayout(LinearLayout.HORIZONTAL, 0);
  106. ArrayList<GoodsInfo> goodsArray = mGoodsHelper.query("1=1");
  107. int i=0;
  108. for (; i<goodsArray.size(); i++) {
  109. final GoodsInfo info = goodsArray.get(i);
  110. LinearLayout ll_goods = newLinearLayout(LinearLayout.VERTICAL, 1);
  111. ll_goods.setBackgroundColor(Color.WHITE);
  112. //添加商品标题
  113. TextView tv_name = new TextView(this);
  114. tv_name.setLayoutParams(mFullParams);
  115. tv_name.setGravity(Gravity.CENTER);
  116. tv_name.setText(info.name);
  117. tv_name.setTextColor(Color.BLACK);
  118. tv_name.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17);
  119. ll_goods.addView(tv_name);
  120. //添加商品小图
  121. ImageView iv_thumb = new ImageView(this);
  122. iv_thumb.setLayoutParams(new LayoutParams(
  123. LayoutParams.MATCH_PARENT, 200));
  124. iv_thumb.setScaleType(ScaleType.FIT_CENTER);
  125. iv_thumb.setImageBitmap(MainApplication.getInstance().mIconMap.get(info.rowid));
  126. iv_thumb.setOnClickListener(new OnClickListener() {
  127. @Override
  128. public void onClick(View v) {
  129. Intent intent = new Intent(ShoppingChannelActivity.this, ShoppingDetailActivity.class);
  130. intent.putExtra("goods_id", info.rowid);
  131. startActivity(intent);
  132. }
  133. });
  134. ll_goods.addView(iv_thumb);
  135. //添加商品价格
  136. LinearLayout ll_bottom = newLinearLayout(LinearLayout.HORIZONTAL, 0);
  137. TextView tv_price = new TextView(this);
  138. tv_price.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 2));
  139. tv_price.setGravity(Gravity.CENTER);
  140. tv_price.setText(""+(int)info.price);
  141. tv_price.setTextColor(Color.RED);
  142. tv_price.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
  143. ll_bottom.addView(tv_price);
  144. //添加购物车按钮
  145. Button btn_add = new Button(this);
  146. btn_add.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 3));
  147. btn_add.setGravity(Gravity.CENTER);
  148. btn_add.setText("加入购物车");
  149. btn_add.setTextColor(Color.BLACK);
  150. btn_add.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
  151. btn_add.setOnClickListener(new OnClickListener() {
  152. @Override
  153. public void onClick(View v) {
  154. addToCart(info.rowid);
  155. Toast.makeText(ShoppingChannelActivity.this,
  156. "已添加一部"+info.name+"到购物车", Toast.LENGTH_SHORT).show();
  157. }
  158. });
  159. ll_bottom.addView(btn_add);
  160. ll_goods.addView(ll_bottom);
  161. //添加商品项目
  162. ll_row.addView(ll_goods);
  163. if (i%2 == 1) {
  164. ll_channel.addView(ll_row);
  165. ll_row = newLinearLayout(LinearLayout.HORIZONTAL, 0);
  166. }
  167. }
  168. if (i%2 == 0) {
  169. ll_row.addView(newLinearLayout(LinearLayout.VERTICAL, 1));
  170. ll_channel.addView(ll_row);
  171. }
  172. }
  173.  
  174. private LinearLayout newLinearLayout(int orientation, int weight) {
  175. LinearLayout ll_new = new LinearLayout(this);
  176. ll_new.setLayoutParams((weight==0)?mFullParams:mHalfParams);
  177. ll_new.setOrientation(orientation);
  178. return ll_new;
  179. }
  180.  
  181. }
  1. ShoppingDetailActivity:
  1. package com.example.alimjan.hello_world;
  2.  
  3. import android.content.Intent;
  4. import android.graphics.Bitmap;
  5. import android.graphics.BitmapFactory;
  6. import android.os.Bundle;
  7. import android.support.v7.app.AppCompatActivity;
  8. import android.view.View;
  9. import android.view.View.OnClickListener;
  10. import android.widget.ImageView;
  11. import android.widget.TextView;
  12. import android.widget.Toast;
  13.  
  14. import com.example.alimjan.hello_world.bean.CartInfo;
  15. import com.example.alimjan.hello_world.bean.GoodsInfo;
  16. import com.example.alimjan.hello_world.dataBase.CartDBHelper;
  17. import com.example.alimjan.hello_world.dataBase.GoodsDBHelper;
  18. import com.example.alimjan.hello_world.Utils.DateUtil;
  19. import com.example.alimjan.hello_world.Utils.SharedUtil;
  20.  
  21. /**
  22. * Created by alimjan on 2017/07/13.
  23. */
  24. public class ShoppingDetailActivity extends AppCompatActivity implements OnClickListener {
  25.  
  26. private TextView tv_title;
  27. private TextView tv_count;
  28. private TextView tv_goods_price;
  29. private TextView tv_goods_desc;
  30. private ImageView iv_goods_pic;
  31. private int mCount;
  32. private long mGoodsId;
  33.  
  34. @Override
  35. protected void onCreate(Bundle savedInstanceState) {
  36. super.onCreate(savedInstanceState);
  37. setContentView(R.layout.activity_shopping_detail);
  38. tv_title = (TextView) findViewById(R.id.tv_title);
  39. tv_count = (TextView) findViewById(R.id.tv_count);
  40. tv_goods_price = (TextView) findViewById(R.id.tv_goods_price);
  41. tv_goods_desc = (TextView) findViewById(R.id.tv_goods_desc);
  42. iv_goods_pic = (ImageView) findViewById(R.id.iv_goods_pic);
  43. findViewById(R.id.iv_cart).setOnClickListener(this);
  44. findViewById(R.id.btn_add_cart).setOnClickListener(this);
  45.  
  46. mCount = Integer.parseInt(SharedUtil.getIntance(this).readShared("count", "0"));
  47. tv_count.setText(""+mCount);
  48. }
  49.  
  50. @Override
  51. public void onClick(View v) {
  52. if (v.getId() == R.id.iv_cart) {
  53. Intent intent = new Intent(this, ShoppingCartActivity.class);
  54. startActivity(intent);
  55. } else if (v.getId() == R.id.btn_add_cart) {
  56. //添加购物车数据库
  57. addToCart(mGoodsId);
  58. Toast.makeText(this, "成功添加至购物车", Toast.LENGTH_SHORT).show();
  59. }
  60. }
  61.  
  62. private void addToCart(long goods_id) {
  63. mCount++;
  64. tv_count.setText(""+mCount);
  65. SharedUtil.getIntance(this).writeShared("count", ""+mCount);
  66. CartInfo info = mCartHelper.queryByGoodsId(goods_id);
  67. if (info != null) {
  68. info.count++;
  69. info.update_time = DateUtil.getCurDateStr("");
  70. mCartHelper.update(info);
  71. } else {
  72. info = new CartInfo();
  73. info.goods_id = goods_id;
  74. info.count = 1;
  75. info.update_time = DateUtil.getCurDateStr("");
  76. mCartHelper.insert(info);
  77. }
  78. }
  79.  
  80. private GoodsDBHelper mGoodsHelper;
  81. private CartDBHelper mCartHelper;
  82.  
  83. @Override
  84. protected void onResume() {
  85. super.onResume();
  86. mGoodsHelper = GoodsDBHelper.getInstance(this, 1);
  87. mGoodsHelper.openReadLink();
  88. mCartHelper = CartDBHelper.getInstance(this, 1);
  89. mCartHelper.openWriteLink();
  90. //展示商品信息
  91. showDetail();
  92. }
  93.  
  94. @Override
  95. protected void onPause() {
  96. super.onPause();
  97. mGoodsHelper.closeLink();
  98. mCartHelper.closeLink();
  99. }
  100.  
  101. private void showDetail() {
  102. mGoodsId = getIntent().getLongExtra("goods_id", 0l);
  103. if (mGoodsId > 0) {
  104. GoodsInfo info = mGoodsHelper.queryById(mGoodsId);
  105. tv_title.setText(info.name);
  106. tv_goods_desc.setText(info.desc);
  107. tv_goods_price.setText(""+info.price);
  108. Bitmap pic = BitmapFactory.decodeFile(info.pic_path);
  109. iv_goods_pic.setImageBitmap(pic);
  110. }
  111. }
  112.  
  113. }
  1. activity_shopping_cart.xml
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:background="#ffffdd"
  5. android:orientation="vertical" >
  6.  
  7. <include layout="@layout/activity_shopping_title" />
  8.  
  9. <ScrollView
  10. android:layout_width="match_parent"
  11. android:layout_height="wrap_content" >
  12.  
  13. <FrameLayout
  14. android:layout_width="match_parent"
  15. android:layout_height="wrap_content"
  16. android:padding="5dp" >
  17.  
  18. <LinearLayout
  19. android:id="@+id/ll_content"
  20. android:layout_width="match_parent"
  21. android:layout_height="wrap_content"
  22. android:orientation="vertical"
  23. android:visibility="gone" >
  24.  
  25. <LinearLayout
  26. android:id="@+id/ll_cart"
  27. android:layout_width="match_parent"
  28. android:layout_height="wrap_content"
  29. android:orientation="vertical" >
  30. </LinearLayout>
  31.  
  32. <LinearLayout
  33. android:layout_width="match_parent"
  34. android:layout_height="wrap_content"
  35. android:orientation="horizontal"
  36. android:padding="10dp" >
  37.  
  38. <TextView
  39. android:layout_width="0dp"
  40. android:layout_height="wrap_content"
  41. android:layout_weight="1"
  42. android:gravity="center|right"
  43. android:text="总金额:"
  44. android:textColor="@color/black"
  45. android:textSize="17sp" />
  46.  
  47. <TextView
  48. android:id="@+id/tv_total_price"
  49. android:layout_width="0dp"
  50. android:layout_height="wrap_content"
  51. android:layout_weight="2"
  52. android:gravity="center|left"
  53. android:textColor="@color/red"
  54. android:textSize="25sp" />
  55.  
  56. <Button
  57. android:id="@+id/btn_settle"
  58. android:layout_width="0dp"
  59. android:layout_height="wrap_content"
  60. android:layout_weight="1"
  61. android:gravity="center"
  62. android:text="结算"
  63. android:textColor="@color/black"
  64. android:textSize="20sp" />
  65. </LinearLayout>
  66.  
  67. </LinearLayout>
  68.  
  69. <LinearLayout
  70. android:id="@+id/ll_empty"
  71. android:layout_width="match_parent"
  72. android:layout_height="wrap_content"
  73. android:orientation="vertical"
  74. android:visibility="gone" >
  75.  
  76. <TextView
  77. android:layout_width="match_parent"
  78. android:layout_height="wrap_content"
  79. android:layout_marginBottom="100dp"
  80. android:layout_marginTop="100dp"
  81. android:gravity="center"
  82. android:text="哎呀,购物车空空如也,快去选购商品吧"
  83. android:textColor="@color/black"
  84. android:textSize="17sp" />
  85.  
  86. <Button
  87. android:id="@+id/btn_shopping_channel"
  88. android:layout_width="match_parent"
  89. android:layout_height="wrap_content"
  90. android:gravity="center"
  91. android:text="逛逛手机商场"
  92. android:textColor="@color/black"
  93. android:textSize="17sp" />
  94. </LinearLayout>
  95. </FrameLayout>
  96. </ScrollView>
  97.  
  98. </LinearLayout>
  1. activity_shopping_channel.xml
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:background="#ffffdd"
  5. android:orientation="vertical" >
  6.  
  7. <include layout="@layout/activity_shopping_title" />
  8.  
  9. <ScrollView
  10. android:layout_width="match_parent"
  11. android:layout_height="wrap_content" >
  12.  
  13. <LinearLayout
  14. android:id="@+id/ll_channel"
  15. android:layout_width="match_parent"
  16. android:layout_height="wrap_content"
  17. android:padding="5dp"
  18. android:orientation="vertical" >
  19. </LinearLayout>
  20. </ScrollView>
  21.  
  22. </LinearLayout>
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:background="#ffffdd"
  5. android:orientation="vertical" >
  6.  
  7. <include layout="@layout/activity_shopping_title" />
  8.  
  9. <ScrollView
  10. android:layout_width="match_parent"
  11. android:layout_height="wrap_content" >
  12.  
  13. <LinearLayout
  14. android:layout_width="match_parent"
  15. android:layout_height="wrap_content"
  16. android:padding="5dp"
  17. android:orientation="vertical" >
  18.  
  19. <ImageView
  20. android:id="@+id/iv_goods_pic"
  21. android:layout_width="match_parent"
  22. android:layout_height="400dp"
  23. android:scaleType="fitCenter" />
  24.  
  25. <TextView
  26. android:id="@+id/tv_goods_price"
  27. android:layout_width="match_parent"
  28. android:layout_height="wrap_content"
  29. android:textColor="@color/red"
  30. android:textSize="22sp" />
  31.  
  32. <TextView
  33. android:id="@+id/tv_goods_desc"
  34. android:layout_width="match_parent"
  35. android:layout_height="wrap_content"
  36. android:textColor="@color/black"
  37. android:textSize="15sp" />
  38.  
  39. <Button
  40. android:id="@+id/btn_add_cart"
  41. android:layout_width="match_parent"
  42. android:layout_height="wrap_content"
  43. android:text="加入购物车"
  44. android:textColor="@color/black"
  45. android:textSize="17sp" />
  46. </LinearLayout>
  47. </ScrollView>
  48.  
  49. </LinearLayout>

  一些工具类:

  1. package com.example.alimjan.hello_world.Utils;
  2.  
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5.  
  6. import java.io.BufferedInputStream;
  7. import java.io.BufferedOutputStream;
  8. import java.io.File;
  9. import java.io.FileInputStream;
  10. import java.io.FileOutputStream;
  11. import java.io.FilenameFilter;
  12. import java.util.ArrayList;
  13. import java.util.Locale;
  14.  
  15. public class FileUtil {
  16.  
  17. public static void saveText(String path, String txt) {
  18. try {
  19. FileOutputStream fos = new FileOutputStream(path);
  20. fos.write(txt.getBytes());
  21. fos.close();
  22. } catch (Exception e) {
  23. e.printStackTrace();
  24. }
  25. }
  26.  
  27. public static String openText(String path) {
  28. String readStr = "";
  29. try {
  30. FileInputStream fis = new FileInputStream(path);
  31. byte[] b = new byte[fis.available()];
  32. fis.read(b);
  33. readStr = new String(b);
  34. fis.close();
  35. } catch (Exception e) {
  36. e.printStackTrace();
  37. }
  38. return readStr;
  39. }
  40.  
  41. public static void saveImage(String path, Bitmap bitmap) {
  42. try {
  43. BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path));
  44. bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
  45. bos.flush();
  46. bos.close();
  47. } catch (Exception e) {
  48. e.printStackTrace();
  49. }
  50. }
  51.  
  52. public static Bitmap openImage(String path) {
  53. Bitmap bitmap = null;
  54. try {
  55. BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
  56. bitmap = BitmapFactory.decodeStream(bis);
  57. bis.close();
  58. } catch (Exception e) {
  59. e.printStackTrace();
  60. }
  61. return bitmap;
  62. }
  63.  
  64. public static ArrayList<File> getFileList(String path, String[] extendArray) {
  65. ArrayList<File> displayedContent = new ArrayList<File>();
  66. File[] files = null;
  67. File directory = new File(path);
  68. if (extendArray != null && extendArray.length>0) {
  69. FilenameFilter fileFilter = getTypeFilter(extendArray);
  70. files = directory.listFiles(fileFilter);
  71. } else {
  72. files = directory.listFiles();
  73. }
  74.  
  75. if (files != null) {
  76. for (File f : files) {
  77. if (!f.isDirectory() && !f.isHidden()) {
  78. displayedContent.add(f);
  79. }
  80. }
  81. }
  82. return displayedContent;
  83. }
  84.  
  85. public static FilenameFilter getTypeFilter(String[] extendArray) {
  86. final ArrayList<String> fileExtensions = new ArrayList<String>();
  87. for (int i=0; i<extendArray.length; i++) {
  88. fileExtensions.add(extendArray[i]);
  89. }
  90. FilenameFilter fileNameFilter = new FilenameFilter() {
  91. @Override
  92. public boolean accept(File directory, String fileName) {
  93. boolean matched = false;
  94. File f = new File(String.format("%s/%s",
  95. directory.getAbsolutePath(), fileName));
  96. matched = f.isDirectory();
  97. if (!matched) {
  98. for (String s : fileExtensions) {
  99. s = String.format(".{0,}\\%s$", s);
  100. s = s.toUpperCase(Locale.getDefault());
  101. fileName = fileName.toUpperCase(Locale.getDefault());
  102. matched = fileName.matches(s);
  103. if (matched) {
  104. break;
  105. }
  106. }
  107. }
  108. return matched;
  109. }
  110. };
  111. return fileNameFilter;
  112. }
  113.  
  114. }
  1. package com.example.alimjan.hello_world.dataBase;
  2.  
  3. import android.content.ContentValues;
  4. import android.content.Context;
  5. import android.database.Cursor;
  6. import android.database.sqlite.SQLiteDatabase;
  7. import android.database.sqlite.SQLiteOpenHelper;
  8. import android.util.Log;
  9.  
  10. import com.example.alimjan.hello_world.bean.GoodsInfo;
  11.  
  12. import java.util.ArrayList;
  13.  
  14. public class GoodsDBHelper extends SQLiteOpenHelper {
  15. private static final String TAG = "GoodsDBHelper";
  16. private static final String DB_NAME = "goods.db";
  17. private static final int DB_VERSION = 1;
  18. private static GoodsDBHelper mHelper = null;
  19. private SQLiteDatabase mDB = null;
  20. private static final String TABLE_NAME = "goods_info";
  21.  
  22. private GoodsDBHelper(Context context) {
  23. super(context, DB_NAME, null, DB_VERSION);
  24. }
  25.  
  26. private GoodsDBHelper(Context context, int version) {
  27. super(context, DB_NAME, null, version);
  28. }
  29.  
  30. public static GoodsDBHelper getInstance(Context context, int version) {
  31. if (version > 0 && mHelper == null) {
  32. mHelper = new GoodsDBHelper(context, version);
  33. } else if (mHelper == null) {
  34. mHelper = new GoodsDBHelper(context);
  35. }
  36. return mHelper;
  37. }
  38.  
  39. public SQLiteDatabase openReadLink() {
  40. if (mDB == null || mDB.isOpen() != true) {
  41. mDB = mHelper.getReadableDatabase();
  42. }
  43. return mDB;
  44. }
  45.  
  46. public SQLiteDatabase openWriteLink() {
  47. if (mDB == null || mDB.isOpen() != true) {
  48. mDB = mHelper.getWritableDatabase();
  49. }
  50. return mDB;
  51. }
  52.  
  53. public void closeLink() {
  54. if (mDB != null && mDB.isOpen() == true) {
  55. mDB.close();
  56. mDB = null;
  57. }
  58. }
  59.  
  60. public String getDBName() {
  61. if (mHelper != null) {
  62. return mHelper.getDatabaseName();
  63. } else {
  64. return DB_NAME;
  65. }
  66. }
  67.  
  68. @Override
  69. public void onCreate(SQLiteDatabase db) {
  70. Log.d(TAG, "onCreate");
  71. String drop_sql = "DROP TABLE IF EXISTS " + TABLE_NAME + ";";
  72. Log.d(TAG, "drop_sql:" + drop_sql);
  73. db.execSQL(drop_sql);
  74. String create_sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " ("
  75. + "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
  76. + "name VARCHAR NOT NULL," + "desc VARCHAR NOT NULL,"
  77. + "price FLOAT NOT NULL," + "thumb_path VARCHAR NOT NULL,"
  78. + "pic_path VARCHAR NOT NULL"
  79. + ");";
  80. Log.d(TAG, "create_sql:" + create_sql);
  81. db.execSQL(create_sql);
  82. }
  83.  
  84. @Override
  85. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  86. }
  87.  
  88. public int delete(String condition) {
  89. int count = mDB.delete(TABLE_NAME, condition, null);
  90. return count;
  91. }
  92.  
  93. public int deleteAll() {
  94. int count = mDB.delete(TABLE_NAME, "1=1", null);
  95. return count;
  96. }
  97.  
  98. public long insert(GoodsInfo info) {
  99. ArrayList<GoodsInfo> infoArray = new ArrayList<GoodsInfo>();
  100. infoArray.add(info);
  101. return insert(infoArray);
  102. }
  103.  
  104. public long insert(ArrayList<GoodsInfo> infoArray) {
  105. long result = -1;
  106. for (int i = 0; i < infoArray.size(); i++) {
  107. GoodsInfo info = infoArray.get(i);
  108. // 如果存在相同rowid的记录,则更新记录
  109. if (info.rowid > 0) {
  110. String condition = String.format("rowid='%d'", info.rowid);
  111. update(info, condition);
  112. result = info.rowid;
  113. continue;
  114. }
  115. // 不存在唯一性重复的记录,则插入新记录
  116. ContentValues cv = new ContentValues();
  117. cv.put("name", info.name);
  118. cv.put("desc", info.desc);
  119. cv.put("price", info.price);
  120. cv.put("thumb_path", info.thumb_path);
  121. cv.put("pic_path", info.pic_path);
  122. result = mDB.insert(TABLE_NAME, "", cv);
  123. // 添加成功后返回行号,失败后返回-1
  124. if (result == -1) {
  125. return result;
  126. }
  127. }
  128. return result;
  129. }
  130.  
  131. public int update(GoodsInfo info, String condition) {
  132. ContentValues cv = new ContentValues();
  133. cv.put("name", info.name);
  134. cv.put("desc", info.desc);
  135. cv.put("price", info.price);
  136. cv.put("thumb_path", info.thumb_path);
  137. cv.put("pic_path", info.pic_path);
  138. int count = mDB.update(TABLE_NAME, cv, condition, null);
  139. return count;
  140. }
  141.  
  142. public int update(GoodsInfo info) {
  143. return update(info, "rowid="+info.rowid);
  144. }
  145.  
  146. public ArrayList<GoodsInfo> query(String condition) {
  147. String sql = String.format("select rowid,_id,name,desc,price,thumb_path,pic_path" +
  148. " from %s where %s;", TABLE_NAME, condition);
  149. Log.d(TAG, "query sql: "+sql);
  150. ArrayList<GoodsInfo> infoArray = new ArrayList<GoodsInfo>();
  151. Cursor cursor = mDB.rawQuery(sql, null);
  152. if (cursor.moveToFirst()) {
  153. for (;; cursor.moveToNext()) {
  154. GoodsInfo info = new GoodsInfo();
  155. info.rowid = cursor.getLong(0);
  156. info.xuhao = cursor.getInt(1);
  157. info.name = cursor.getString(2);
  158. info.desc = cursor.getString(3);
  159. info.price = cursor.getFloat(4);
  160. info.thumb_path = cursor.getString(5);
  161. info.pic_path = cursor.getString(6);
  162. infoArray.add(info);
  163. if (cursor.isLast() == true) {
  164. break;
  165. }
  166. }
  167. }
  168. cursor.close();
  169. return infoArray;
  170. }
  171.  
  172. public GoodsInfo queryById(long rowid) {
  173. GoodsInfo info = null;
  174. ArrayList<GoodsInfo> infoArray = query(String.format("rowid='%d'", rowid));
  175. if (infoArray.size() > 0) {
  176. info = infoArray.get(0);
  177. }
  178. return info;
  179. }
  180.  
  181. }
  1. package com.example.alimjan.hello_world.dataBase;
  2.  
  3. import android.content.ContentValues;
  4. import android.content.Context;
  5. import android.database.Cursor;
  6. import android.database.sqlite.SQLiteDatabase;
  7. import android.database.sqlite.SQLiteOpenHelper;
  8. import android.util.Log;
  9.  
  10. import com.example.alimjan.hello_world.bean.CartInfo;
  11.  
  12. import java.util.ArrayList;
  13.  
  14. public class CartDBHelper extends SQLiteOpenHelper {
  15. private static final String TAG = "CartDBHelper";
  16. private static final String DB_NAME = "cart.db";
  17. private static final int DB_VERSION = 1;
  18. private static CartDBHelper mHelper = null;
  19. private SQLiteDatabase mDB = null;
  20. private static final String TABLE_NAME = "cart_info";
  21.  
  22. private CartDBHelper(Context context) {
  23. super(context, DB_NAME, null, DB_VERSION);
  24. }
  25.  
  26. private CartDBHelper(Context context, int version) {
  27. super(context, DB_NAME, null, version);
  28. }
  29.  
  30. public static CartDBHelper getInstance(Context context, int version) {
  31. if (version > 0 && mHelper == null) {
  32. mHelper = new CartDBHelper(context, version);
  33. } else if (mHelper == null) {
  34. mHelper = new CartDBHelper(context);
  35. }
  36. return mHelper;
  37. }
  38.  
  39. public SQLiteDatabase openReadLink() {
  40. if (mDB == null || mDB.isOpen() != true) {
  41. mDB = mHelper.getReadableDatabase();
  42. }
  43. return mDB;
  44. }
  45.  
  46. public SQLiteDatabase openWriteLink() {
  47. if (mDB == null || mDB.isOpen() != true) {
  48. mDB = mHelper.getWritableDatabase();
  49. }
  50. return mDB;
  51. }
  52.  
  53. public void closeLink() {
  54. if (mDB != null && mDB.isOpen() == true) {
  55. mDB.close();
  56. mDB = null;
  57. }
  58. }
  59.  
  60. public String getDBName() {
  61. if (mHelper != null) {
  62. return mHelper.getDatabaseName();
  63. } else {
  64. return DB_NAME;
  65. }
  66. }
  67.  
  68. @Override
  69. public void onCreate(SQLiteDatabase db) {
  70. Log.d(TAG, "onCreate");
  71. String drop_sql = "DROP TABLE IF EXISTS " + TABLE_NAME + ";";
  72. Log.d(TAG, "drop_sql:" + drop_sql);
  73. db.execSQL(drop_sql);
  74. String create_sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " ("
  75. + "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
  76. + "goods_id LONG NOT NULL," + "count INTEGER NOT NULL,"
  77. + "update_time VARCHAR NOT NULL"
  78. + ");";
  79. Log.d(TAG, "create_sql:" + create_sql);
  80. db.execSQL(create_sql);
  81. }
  82.  
  83. @Override
  84. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  85. }
  86.  
  87. public int delete(String condition) {
  88. int count = mDB.delete(TABLE_NAME, condition, null);
  89. return count;
  90. }
  91.  
  92. public int deleteAll() {
  93. int count = mDB.delete(TABLE_NAME, "1=1", null);
  94. return count;
  95. }
  96.  
  97. public long insert(CartInfo info) {
  98. ArrayList<CartInfo> infoArray = new ArrayList<CartInfo>();
  99. infoArray.add(info);
  100. return insert(infoArray);
  101. }
  102.  
  103. public long insert(ArrayList<CartInfo> infoArray) {
  104. long result = -1;
  105. for (int i = 0; i < infoArray.size(); i++) {
  106. CartInfo info = infoArray.get(i);
  107. Log.d(TAG, "goods_id="+info.goods_id+", count="+info.count);
  108. // 如果存在相同rowid的记录,则更新记录
  109. if (info.rowid > 0) {
  110. String condition = String.format("rowid='%d'", info.rowid);
  111. update(info, condition);
  112. result = info.rowid;
  113. continue;
  114. }
  115. // 不存在唯一性重复的记录,则插入新记录
  116. ContentValues cv = new ContentValues();
  117. cv.put("goods_id", info.goods_id);
  118. cv.put("count", info.count);
  119. cv.put("update_time", info.update_time);
  120. result = mDB.insert(TABLE_NAME, "", cv);
  121. // 添加成功后返回行号,失败后返回-1
  122. if (result == -1) {
  123. return result;
  124. }
  125. }
  126. return result;
  127. }
  128.  
  129. public int update(CartInfo info, String condition) {
  130. ContentValues cv = new ContentValues();
  131. cv.put("goods_id", info.goods_id);
  132. cv.put("count", info.count);
  133. cv.put("update_time", info.update_time);
  134. int count = mDB.update(TABLE_NAME, cv, condition, null);
  135. return count;
  136. }
  137.  
  138. public int update(CartInfo info) {
  139. return update(info, "rowid="+info.rowid);
  140. }
  141.  
  142. public ArrayList<CartInfo> query(String condition) {
  143. String sql = String.format("select rowid,_id,goods_id,count,update_time" +
  144. " from %s where %s;", TABLE_NAME, condition);
  145. Log.d(TAG, "query sql: "+sql);
  146. ArrayList<CartInfo> infoArray = new ArrayList<CartInfo>();
  147. Cursor cursor = mDB.rawQuery(sql, null);
  148. if (cursor.moveToFirst()) {
  149. for (;; cursor.moveToNext()) {
  150. CartInfo info = new CartInfo();
  151. info.rowid = cursor.getLong(0);
  152. info.xuhao = cursor.getInt(1);
  153. info.goods_id = cursor.getLong(2);
  154. info.count = cursor.getInt(3);
  155. info.update_time = cursor.getString(4);
  156. infoArray.add(info);
  157. if (cursor.isLast() == true) {
  158. break;
  159. }
  160. }
  161. }
  162. cursor.close();
  163. return infoArray;
  164. }
  165.  
  166. public CartInfo queryById(long rowid) {
  167. CartInfo info = null;
  168. ArrayList<CartInfo> infoArray = query(String.format("rowid='%d'", rowid));
  169. if (infoArray.size() > 0) {
  170. info = infoArray.get(0);
  171. }
  172. return info;
  173. }
  174.  
  175. public CartInfo queryByGoodsId(long goods_id) {
  176. CartInfo info = null;
  177. ArrayList<CartInfo> infoArray = query(String.format("goods_id='%d'", goods_id));
  178. if (infoArray.size() > 0) {
  179. info = infoArray.get(0);
  180. }
  181. return info;
  182. }
  183.  
  184. }
  1. package com.example.alimjan.hello_world.bean;
  2.  
  3. public class GoodsInfo {
  4. public long rowid;
  5. public int xuhao;
  6. public String name;
  7. public String desc;
  8. public float price;
  9. public String thumb_path;
  10. public String pic_path;
  11.  
  12. public GoodsInfo() {
  13. rowid = 0l;
  14. xuhao = 0;
  15. name = "";
  16. desc = "";
  17. price = 0;
  18. thumb_path = "";
  19. pic_path = "";
  20. }
  21. }
  1. package com.example.alimjan.hello_world.bean;
  2.  
  3. public class CartInfo {
  4. public long rowid;
  5. public int xuhao;
  6. public long goods_id;
  7. public int count;
  8. public String update_time;
  9.  
  10. public CartInfo() {
  11. rowid = 0l;
  12. xuhao = 0;
  13. goods_id = 0l;
  14. count = 0;
  15. update_time = "";
  16. }
  17. }
  1. <menu xmlns:android="http://schemas.android.com/apk/res/android" >
  2.  
  3. <item
  4. android:id="@+id/menu_shopping"
  5. android:orderInCategory="1"
  6. android:title="去商场购物"/>
  7.  
  8. <item
  9. android:id="@+id/menu_clear"
  10. android:orderInCategory="2"
  11. android:title="清空购物车"/>
  12.  
  13. <item
  14. android:id="@+id/menu_return"
  15. android:orderInCategory="9"
  16. android:title="返回"/>
  17.  
  18. </menu>
  1. <menu xmlns:android="http://schemas.android.com/apk/res/android" >
  2.  
  3. <item
  4. android:id="@+id/menu_detail"
  5. android:orderInCategory="1"
  6. android:title="查看商品详情"/>
  7.  
  8. <item
  9. android:id="@+id/menu_delete"
  10. android:orderInCategory="2"
  11. android:title="从购物车删除"/>
  12.  
  13. </menu>
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:shape="oval" >
  4.  
  5. <solid android:color="#ff6666" />
  6.  
  7. </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. Java基础——集合源码解析 List List 接口

    今天我们来学习集合的第一大体系 List. List 是一个接口,定义了一组元素是有序的.可重复的集合. List 继承自 Collection,较之 Collection,List 还添加了以下操作 ...

  2. 记XDCTF的misc之旅---base64隐写

    bWFpbigpe2ludCBpLG5bXT17KCgoMSA8PDEpPDwgKDE8PDEpPDwoMTw8Cm==ICAgICAgIDEpPDwoMTw8KDE+PjEpKSkrKCgxPDwx ...

  3. 组合 Lucas定理

    组合 Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u [Submit]   [Go Ba ...

  4. uva11806

    [题意] n行m列网格放k个石子.有多少种方法?要求第一行,第一列,最后一行,最后一列必须有石子. [题解] 利用容斥原理.可以转到求"第一行.第一列.最后一行.最后一列没有石子" ...

  5. 【Spring】面向切面之AOP

    前言 前面已经讲解了bean的装配技术,接着学习Spring中另外一个核心概念:切面. 面向切面 面向切面编程 切面能够帮助模块化横切关注点,横切关注点可以被描述为影响应用的功能,如为业务添加安全和事 ...

  6. 最好用的css辅助工具——SASS&LESS

    前言 首先,小编给大家解释一下什么是SCSS和LESS,Sass 是一款强化 CSS 的辅助工具,它在 CSS 语法的基础上增加了变量 (variables).嵌套 (nested rules).混合 ...

  7. H264常见术语名称

    一.术语 帧(frame)和场(field):一帧包含一个亮度矩阵采样点和俩个对应的色度矩阵采样点,一帧包含俩个场:顶场和底场: 条带:特定条带组按光栅扫描顺序排列的整数个宏块或宏块对: 条带组:图像 ...

  8. FPGA IN 消费电子

    消费电子: 消费电子(Consumer electronics),指供日常消费者生活使用的电子产品.消费类电子产品是指用于个人和家庭与广播.电视有关的音频和视频产品,主要包括:电视机.影碟机(VCD. ...

  9. Tensorflow卷积神经网络

    卷积神经网络(Convolutional Neural Network, CNN)是一种前馈神经网络, 在计算机视觉等领域被广泛应用. 本文将简单介绍其原理并分析Tensorflow官方提供的示例. ...

  10. ZOJ1171

    错误代码先放这 #include<cstdio> #include<cstdlib> #include<iostream> #include<cstring& ...