这是一个商品添加到购物车的小demo,有登录注册,商品列表,添加购物车,移除购物车等功能,基于Sqlite实现对数据的增删改查。
完整代码下载:https://download.csdn.net/download/always_and_forever_/73729108
下面是代码解读,适合新手阅读学习:
1.登录页面--LoginActivity
1.页面包含两个文本输入框,用来输入用户名和密码,一个登录按钮,一个注册按钮。
2.点击登录则验证用户名密码输入是否为空,为空则给出提示,不为空则根据输入的用户名和密码查询数据库,根据查询结果判断是否存在该用户;若存在则将当前用户名、性别信息存储在SharedPreferences中,以便在我的页面查看,然后跳转到首页,并将当前用户名通过Intent传值到首页,在跳转到首页时,提示“欢迎xx登录”,若不存在则给出提示:用户名或密码错误
List<UserBean> list = SQLiteDbUtil.getSQLiteDbUtil().query(UserBean.class,"name=? and pwd=?",new String[]{name,pwd});
if (list == null || list.size() == 0){
Toast.makeText(this, "用户名或密码错误", Toast.LENGTH_LONG).show();
return;
}
UserBean user = list.get(0);
//存到SharedPreferences工具类
SPUtil.saveString(this,"name",name);
SPUtil.saveString(this,"sexName",user.getSexName());
3.点击注册跳转到注册页面。
2.注册页面--RegisterActivity
1.页面包含两个文本输入框,用户输入用户名和密码,一个spinner下拉,用来选择性别,性别默认为空,一个注册按钮
2.为spinner设置数据源和适配器,以及选中事件,选中时重新标记mSexName变量,mSexName是性别名称变量,值为男或女,默认是男
String[] sexItems = new String[]{"男", "女"};
mSexName = sexItems[0];
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, sexItems);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerAdapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mSexName = sexItems[position];
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
3.点击注册时,判断用户名和密码输入是否为空,为空则给出提示,不为空则新增一条User记录,插入到数据库,插入之前先判断输入的用户名是否已经存在了,若存在则提示用户名已被注册
List<UserBean> list = SQLiteDbUtil.getSQLiteDbUtil().query(UserBean.class,"name=?",new String[]{name});
if (list != null && list.size() > 0){
Toast.makeText(this, "该用户名已被注册", Toast.LENGTH_LONG).show();
return;
}
UserBean user = new UserBean(name,pwd,mSexName);
SQLiteDbUtil.getSQLiteDbUtil().insert(user);
4.插入成功后,关闭当前页面,回到登录页面进行登录
3.首页--MainActiivty
1.首页布局使用viewpager+fragment,fragment有三个,分别是商品、购物车、我的
2.为viewpager的适配器设置数据,表示将有上述三个页面会被显示到viewpager,默认显示商品页面
MyFragment myFragment = new MyFragment();
List<Fragment> fragmentList = new ArrayList<>();
fragmentList.add(foodFragment);
fragmentList.add(cartFragment);
fragmentList.add(myFragment);
mFragmentAdapter.refreshUi(fragmentList);
mViewPager.setOffscreenPageLimit(fragmentList.size());
3.商品页面展示商品列表,购物车展示已加入购物车的商品,我的展示当前登录用户信息等
4.通过getIntent取登录页面传来的name值,并提示欢迎xx登录
5.商品、购物车、我的页面切换时,通过viewpager.setCurrentItem指定
6.页面初始化时会查询数据库购物车列表,并添加到Bundle,并将Bundle通过fragment.setArguments,传递给fragment
if (list != null){
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("datas", (ArrayList<? extends Parcelable>) list);
cartFragment.setArguments(bundle);
}
4.商品页面--FoodFragment
1.页面布局使用TabHost+ListView,其中Tab有三个,分别是美食、饮品、水果,ListView也有三个,分别展示每个tab对应的数据
以下为初始化tabHost,并为其设置tab名称,绑定对应的tab布局,每个tab都是listview,用来显示对应tab数据
mListView1 = view.findViewById(R.id.lv_food1);
mListView2 = view.findViewById(R.id.lv_food2);
mListView3 = view.findViewById(R.id.lv_food3);
mAdapter1 = new ListFoodAdapter(getActivity());
mAdapter2 = new ListFoodAdapter(getActivity());
mAdapter3 = new ListFoodAdapter(getActivity());
mListView1.setAdapter(mAdapter1);
mListView2.setAdapter(mAdapter2);
mListView3.setAdapter(mAdapter3);
TabHost tab = view.findViewById(R.id.tab);
tab.setup();
//创建Tab标签
tab.addTab(tab.newTabSpec("one").setIndicator("美食").setContent(R.id.tab1));
tab.addTab(tab.newTabSpec("two").setIndicator("饮品").setContent(R.id.tab2));
tab.addTab(tab.newTabSpec("two").setIndicator("水果").setContent(R.id.tab3));
2.初始化时,构造测试数据,分别是美食商品的测试数据,饮品的测试数据、水果的测试数据,每组分别有10条数据
String[] delicacy = new String[]{
"精致便当","真牛铁板板","八块八","肯德基宅急送","正新鸡排","必胜客宅急送","麦当劳","三个先森的韩国炸鸡","绝味鸭脖","华莱士"
};
String[] delicacy_price = new String[]{
"17.7","30.8","18.0","17.7","26.9","24.9","30.0","33","19","21.3"
};
String[] drink = new String[]{
"黄桃果霸","珍珠奶茶","桃桃摇摇奶昔","满杯百香果","蜜桃四季春","棒打鲜橙","柠萌绿茶","柠萌红茶","森林玫果","冰鲜柠萌水"
};
String[] drink_price = new String[]{
"8.9","10.8","18.2","5","8","9","12","15","5","11"
};
String[] fruit = new String[]{
"香蕉","柠萌","苹果","草莓","西瓜","桃","柚子","梨","哈密瓜","葡萄"
};
String[] fruit_price = new String[]{
"3","8.9","8","12","5","1.2","2.3","8","6","11"
};
3.为listview设置适配器,并分别设置对应的测试数据
mAdapter1.refreshUi(foodList_delicacy);
mAdapter2.refreshUi(foodList_drink);
mAdapter3.refreshUi(foodList_fruit);
4.切换tab时即可看到对应tab下的商品数据,例如点击美食,看到的就是美食列表、点击饮品看到的就是饮品列表
5.点击添加购物车,即可将当前商品添加到购物车,添加时,先查询数据库该商品是否已经添加过了,若添加过,则数量加1并更新数据库,否则新建一条购物车记录数据,添加到数据库
FoodBean _bean = (FoodBean)v.getTag();
List<CartBean> list = SQLiteDbUtil.getSQLiteDbUtil().query(CartBean.class,"name=?",new String[]{_bean.getName()});
if (list != null && list.size() == 1){//已添加过,改下数量
CartBean cart = list.get(0);
cart.setNum(cart.getNum() + 1);
SQLiteDbUtil.getSQLiteDbUtil().update(cart,cart.getId());
}else {
CartBean cartBean = new CartBean(_bean.getName(),_bean.getPrice());
cartBean.setNum(1);
SQLiteDbUtil.getSQLiteDbUtil().insert(cartBean);
}
Toast.makeText(mContext,"添加成功",Toast.LENGTH_SHORT).show();
5.购物车页面--CartFragment
1.页面布局是一个ListView,用来显示购物车列表
2.通过getArguments获取MainActivity传来的购物车列表,并设置给listview的适配器
//获取bundle数据
Bundle bundle = getArguments();
if (bundle != null && bundle.getParcelableArrayList("datas") != null){
List<CartBean> list = SQLiteDbUtil.getSQLiteDbUtil().query(CartBean.class);
if (list != null){
mAdapter.refreshUi(list);
}
}
3.通过setUserVisibleHint方法,判断当前页面是否正在展示,若正在展示,则查询数据库最新的购物车列表,设置给listview的适配器
//可见时刷新数据
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser){
List<CartBean> list = SQLiteDbUtil.getSQLiteDbUtil().query(CartBean.class);
if (list != null){
mAdapter.refreshUi(list);
}
}
}
4.列表中显示商品名称,已添加的数量,并通过数量*单价求出总价,点击移除购物车,则将数量-1,减到0时,则表示完全移除购物车,每次点击移除购物车时,会有对话框提示,点击取消则取消,点击确定才会进行移除操作
new AlertDialog.Builder(mContext).setTitle("移除提示").setMessage("确定移除购物车吗?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
CartBean _bean = (CartBean) v.getTag();
int _num = _bean.getNum() - 1;
_bean.setNum(_num);
if (_num == 0) {
//移除并刷新页面
SQLiteDbUtil.getSQLiteDbUtil().delete(CartBean.class, _bean.getId());
} else {
//更新数据库
SQLiteDbUtil.getSQLiteDbUtil().update(_bean, _bean.getId());
}
mDatas = SQLiteDbUtil.getSQLiteDbUtil().query(CartBean.class);
notifyDataSetChanged();
}
}).setNegativeButton("取消", null)
.create()
.show();
6.我的页面--MyFragment
1.页面两个文本,分别显示当前登录用户名称已用户性别,一个退出登录按钮,点击则跳转到登录页面
2.用户名和性别,通过SharedPreferences来获取,登录时已经通过SharedPreferences做了保存,这里只要读取即可
//取sp数据
String name = SPUtil.getString(getActivity(),"name","未知用户");
String sexName = SPUtil.getString(getActivity(),"sexName","未知性别");
tv_name.setText(name);
tv_sex_name.setText(sexName);
其他
SQLiteDbUtil
这是对原生SQLite的封装,支持增删改查,创建表,创建数据库等操作
SPUtil
这是对原生SharedPreferences的封装,支持字符串和数值类型的数据存储与读取
App
是程序的主入口,初始化时会创建数据库和三张表,数据库若已经存在了则不会创建,表也同理
其中FoodBean表没用到,因为用的是测试数据
UserBean是用户表,存储用户名与密码
CartBean是购物车表,存储每一条添加到购物车的数据
SQLiteDbUtil.getSQLiteDbUtil().openOrCreateDataBase(this,null);
SQLiteDbUtil.getSQLiteDbUtil().createTable(UserBean.class);
SQLiteDbUtil.getSQLiteDbUtil().createTable(FoodBean.class);
SQLiteDbUtil.getSQLiteDbUtil().createTable(CartBean.class);