//数据库创建
```java
package soexample.umeng.com.day_04_greendao.app;
import android.app.Application;
import soexample.umeng.com.day_04_greendao.dao.DaoMaster;
import soexample.umeng.com.day_04_greendao.dao.DaoSession;
public class MyApp extends Application {
private static DaoSession mDaoSession;
@Override
public void onCreate() {
super.onCreate();
initDatabase();
}
private void initDatabase() {
//创建数据库
DaoMaster.DevOpenHelper openHelper = new DaoMaster.DevOpenHelper(this, "xxlv.db");
//用greenDao的Daomaster来包装这个数据库
DaoMaster daoMaster = new DaoMaster(openHelper.getWritableDatabase());
mDaoSession = daoMaster.newSession();
}
public static DaoSession getDaoSession() {
return mDaoSession;
}
}
* GreenDao数据库
* 怎么使用:
* 1:导入依赖
* 1:Project下classpath classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
* 2:model下的build.gradle 第一行 apply plugin: 'org.greenrobot.greendao'
* 导入两个依赖
* implementation 'org.greenrobot:greendao:3.2.2'
* implementation 'org.greenrobot:greendao-generator:3.2.2'
* 3:在Android代码中加入
* greendao {
* //指定数据库schema版本号,迁移等操作会用到
* schemaVersion 1
* //DaoSession、DaoMaster以及所有实体类的dao生成的目录,默认为你的entity所在的包名
* //daoPackage 包名
* daoPackage 'soexample.umeng.com.day_04_greendao.dao'
* //这就是我们上面说到的自定义生成数据库文件的目录了,可以将生成的文件放到我们的java目录中,而不是build中,这样就不用额外的设置资源目录了
* //工程路径
* targetGenDir 'src/main/java'
* }
*
* 以上配置OK就可以使用greendao
* 写一个实体类然后在外部加上一个注解
*
* @Id注解选择 long / Long 属性作为实体ID。在数据库术语中,它是主键。参数自动增量,是使ID值不断增加(不会选用旧值)的标志。
* @Property让你定义一个非默认的列名,其属性映射到。如果不存在,greenDAO将在SQL杂交方式使用字段名(大写,下划线,而不是骆驼情况下,例如 customName将成为 CUSTOM_NAME)。注意:您目前只能使用内联常量来指定列名。
* @NotNull makes the property a “NOT NULL” column on the database side。通常是有意义的纪念原始类型(long, int, short, byte)与@NotNull,同时具有包装类(Long, Integer, Short, Byte)空的值。
* @Transient表明这个字段不会被写入数据库,只是作为一个普通的java类字段,用来临时存储数据的,不会被持久化
* @Entity 定义实体
* @nameInDb 在数据库中的名字,如不写则为实体中类名
* @indexes 索引
* @createInDb 是否创建表,默认为true,false时不创建
* @schema 指定架构名称为实体
* @active 无论是更新生成都刷新
* @Id
* @NotNull 不为null
* @Unique 唯一约束
* @ToMany 一对多
* @OrderBy 排序
* @ToOne 一对一
* @Transient 不存储在数据库中
* @generated 由greendao产生的构造函数或方法
*
* 写完字段过后 需要make project锤子锤一下即可
*
* DaoMaster 创建数据库
* DaoSession 管理绑定表
* XXXDao
*
* 我们抽取代码在Application操作
* private void initDatabase() {
* //创建数据库
* DaoMaster.DevOpenHelper openHelper = new DaoMaster.DevOpenHelper(this, "xxlv.db");
* //用greenDao的Daomaster来包装这个数据库
* DaoMaster daoMaster = new DaoMaster(openHelper.getWritableDatabase());
* mDaoSession = daoMaster.newSession();
* }
*
* 扩展知识 数据库升级 一般只要数据库定下来 字段就不能随便改了
* 序列化和反序列化 高频面试问题
* 一个Android Parcelable 一个是java Serializable
* 如果你这个实体类用序列化必须要加安全的UID
* private static final long serialVersionUID = -4211449776975163975L;```
//二级列表适配器
```java
package soexample.umeng.com.day07_shopping_car_demo.adapter;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.List;
import soexample.umeng.com.day07_shopping_car_demo.R;
import soexample.umeng.com.day07_shopping_car_demo.bean.MyData;
import soexample.umeng.com.day07_shopping_car_demo.weight.MyAddOrRemoveView;
public class MyExpanAdapter extends BaseExpandableListAdapter {
private List<MyData.ResultBean> mList;
private Context mContext;
public MyExpanAdapter(List<MyData.ResultBean> mList, Context mContext) {
this.mList = mList;
this.mContext = mContext;
}
@Override
public int getGroupCount() {
return mList.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return mList.get(groupPosition).getShoppingCartList().size();
}
@Override
public Object getGroup(int groupPosition) {
return null;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return null;
}
@Override
public long getGroupId(int groupPosition) {
return 0;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupHolder holder = null;
if (convertView == null) {
holder = new GroupHolder();
convertView = View.inflate(mContext, R.layout.recy_big, null);
holder.mBigCheck = convertView.findViewById(R.id.Big_CheckBox);
holder.mBigTv = convertView.findViewById(R.id.Big_Text);
convertView.setTag(holder);
} else {
holder = (GroupHolder) convertView.getTag();
}
holder.mBigTv.setText(mList.get(groupPosition).getCategoryName() + "");
holder.mBigCheck.setChecked(setBigCheck(groupPosition));
holder.mBigCheck.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (callback != null) {
callback.bigCheckClick(groupPosition);
}
}
});
return convertView;
}
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ChildHolder holder = null;
if (convertView == null) {
holder = new ChildHolder();
convertView = View.inflate(mContext, R.layout.recy_samll, null);
holder.mSmallCheck = convertView.findViewById(R.id.small_Check);
holder.mSmallName = convertView.findViewById(R.id.small_Name);
holder.mPrice = convertView.findViewById(R.id.small_Price);
holder.mImage = convertView.findViewById(R.id.samll_Image);
holder.myAddOrRemoveView = convertView.findViewById(R.id.AddOrRemove);
convertView.setTag(holder);
} else {
holder = (ChildHolder) convertView.getTag();
}
MyData.ResultBean.ShoppingCartListBean bean = mList.get(groupPosition).getShoppingCartList().get(childPosition);
holder.mSmallName.setText(bean.getCommodityName() + "");
holder.mPrice.setText(bean.getPrice() + "");
holder.myAddOrRemoveView.setNumber(bean.getCount());
Glide.with(mContext).load(bean.getPic()).into(holder.mImage);
holder.mSmallCheck.setChecked(bean.isStatus());
holder.mSmallCheck.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (callback != null) {
callback.smallCheckClick(groupPosition, childPosition);
}
}
});
holder.myAddOrRemoveView.setItemCount(new MyAddOrRemoveView.ItemCount() {
@Override
public void setItemCount(int number) {
if (callback!=null){
callback.smallCheckClickCount(groupPosition, childPosition,number);
}
}
});
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
class GroupHolder {
private CheckBox mBigCheck;
private TextView mBigTv;
}
class ChildHolder {
private CheckBox mSmallCheck;
private TextView mSmallName, mPrice;
private ImageView mImage;
private MyAddOrRemoveView myAddOrRemoveView;
}
public interface ShoppingCallback {
void bigCheckClick(int bigIndex);
void smallCheckClick(int bigIndex, int smallIndex);
void smallCheckClickCount(int bigIndex, int smallIndex, int number);
}
private ShoppingCallback callback;
public void setCallback(ShoppingCallback callback) {
this.callback = callback;
}
//接下来就是业务逻辑方法的时候了
//判断商家是否要选中
public boolean setBigCheck(int bigIndex) {
boolean flag = true;
MyData.ResultBean resultBean = mList.get(bigIndex);
for (int i = 0; i < resultBean.getShoppingCartList().size(); i++) {
if (!resultBean.getShoppingCartList().get(i).isStatus()) {
flag = false;
return flag;
}
}
return flag;
}
//当我点击商家的复选框的时候
public void setBigCheckStatus(int bigIndex, boolean isStatus) {
List<MyData.ResultBean.ShoppingCartListBean> cartList = mList.get(bigIndex).getShoppingCartList();
for (MyData.ResultBean.ShoppingCartListBean cardBean : cartList) {
cardBean.setStatus(isStatus);
}
}
//当我点击商品让他选中
public void setSmallCheck(int bigIndex, int smallIndex, boolean isCheck) {
mList.get(bigIndex).getShoppingCartList().get(smallIndex).setStatus(isCheck);
}
//当我点击Activity中的全选按钮式
public boolean isAllChecked() {
boolean isAllchecked = true;
for (int i = 0; i < mList.size(); i++) {
List<MyData.ResultBean.ShoppingCartListBean> shoppingCartList = mList.get(i).getShoppingCartList();
for (int j = 0; j < shoppingCartList.size(); j++) {
if (!shoppingCartList.get(j).isStatus()) {
isAllchecked = false;
return isAllchecked;
}
}
}
return isAllchecked;
}
public void setAllChecked(boolean isCheck) {
for (int i = 0; i < mList.size(); i++) {
List<MyData.ResultBean.ShoppingCartListBean> shoppingCartList = mList.get(i).getShoppingCartList();
for (int j = 0; j < shoppingCartList.size(); j++) {
shoppingCartList.get(j).setStatus(isCheck);
}
}
}
//计算总价格
public int allPrice() {
int allprice = 0;
for (int i = 0; i < mList.size(); i++) {
List<MyData.ResultBean.ShoppingCartListBean> shoppingCartList = mList.get(i).getShoppingCartList();
for (int j = 0; j < shoppingCartList.size(); j++) {
if (shoppingCartList.get(j).isStatus()) {
allprice += shoppingCartList.get(j).getPrice() * shoppingCartList.get(j).getCount();
}
}
}
return allprice;
}
//计算总数量
public int allNumber() {
int count = 0;
for (int i = 0; i < mList.size(); i++) {
List<MyData.ResultBean.ShoppingCartListBean> shoppingCartList = mList.get(i).getShoppingCartList();
for (int j = 0; j < shoppingCartList.size(); j++) {
if (shoppingCartList.get(j).isStatus()) {
count += shoppingCartList.get(j).getCount();
}
}
}
return count;
}
}
//自定义View回调加减器
```java
```java
package soexample.umeng.com.day07_shopping_car_demo.weight;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import soexample.umeng.com.day07_shopping_car_demo.R;
public class MyAddOrRemoveView extends LinearLayout implements View.OnClickListener {
private TextView mAdd, mNumber, mRemove;
public MyAddOrRemoveView(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.add_remove_layout, this);
initViews();
}
public void setNumber(int number) {
mNumber.setText(number + "");
}
private void initViews() {
mAdd = findViewById(R.id.Add);
mNumber = findViewById(R.id.Number);
mRemove = findViewById(R.id.Remove);
mAdd.setOnClickListener(this);
mRemove.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int count = Integer.parseInt(mNumber.getText().toString());
switch (v.getId()) {
case R.id.Add:
count++;
mNumber.setText(count + "");
if (itemCount != null) {
itemCount.setItemCount(count);
}
break;
case R.id.Remove:
if (count > 1) {
count--;
mNumber.setText(count + "");
if (itemCount != null) {
itemCount.setItemCount(count);
}
} else {
Toast.makeText(getContext(), "数量最少为1", Toast.LENGTH_SHORT).show();
}
break;
}
}
public interface ItemCount {
void setItemCount(int number);
}
private ItemCount itemCount;
public void setItemCount(ItemCount itemCount) {
this.itemCount = itemCount;
}
}
//展示页面
```java
package soexample.umeng.com.day07_shopping_car_demo;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import soexample.umeng.com.day07_shopping_car_demo.adapter.MyExpanAdapter;
import soexample.umeng.com.day07_shopping_car_demo.base.BaseActivity;
import soexample.umeng.com.day07_shopping_car_demo.base.BasePresenter;
import soexample.umeng.com.day07_shopping_car_demo.bean.MyData;
import soexample.umeng.com.day07_shopping_car_demo.presenter.PresenterImpl;
import soexample.umeng.com.day07_shopping_car_demo.url.MyUrls;
public class ExpanableDemoActivity extends BaseActivity {
private ExpandableListView Expan_ListView;
private CheckBox All_check;
private TextView All_Price;
private TextView All_Count;
private LinearLayout bottom_layout;
private List mList = new ArrayList<>();
private MyExpanAdapter mAdapter;
@Override
public BasePresenter getPresenter() {
return new PresenterImpl();
}
@Override
public int getLayoutId() {
return R.layout.activity_expanable_demo;
}
@Override
public void startCoding() {
mAdapter = new MyExpanAdapter(mList, this);
Expan_ListView.setAdapter(mAdapter);
Map map = new HashMap<>();
map.put("userId", "10922");
map.put("sessionId", "157559325456410922");
mPresenter.startGetRequest(MyUrls.SHOPPINGCARD, MyData.class, map);
mAdapter.setCallback(new MyExpanAdapter.ShoppingCallback() {
@Override
public void bigCheckClick(int bigIndex) {
boolean b = mAdapter.setBigCheck(bigIndex);
mAdapter.setBigCheckStatus(bigIndex, !b);
mAdapter.notifyDataSetChanged();
allCalculation();
}
@Override
public void smallCheckClick(int bigIndex, int smallIndex) {
boolean status = mList.get(bigIndex).getShoppingCartList().get(smallIndex).isStatus();
mAdapter.setSmallCheck(bigIndex, smallIndex, !status);
mAdapter.notifyDataSetChanged();
allCalculation();
}
@Override
public void smallCheckClickCount(int bigIndex, int smallIndex, int number) {
mList.get(bigIndex).getShoppingCartList().get(smallIndex).setCount(number);
mAdapter.notifyDataSetChanged();
allCalculation();
}
});
}
@Override
public void initViews() {
Expan_ListView = (ExpandableListView) findViewById(R.id.Expan_ListView);
All_check = (CheckBox) findViewById(R.id.All_check);
All_Price = (TextView) findViewById(R.id.All_Price);
All_Count = (TextView) findViewById(R.id.All_Count);
bottom_layout = (LinearLayout) findViewById(R.id.bottom_layout);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.All_check:
boolean allChecked = mAdapter.isAllChecked();
mAdapter.setAllChecked(!allChecked);
All_check.setChecked(!allChecked);
mAdapter.notifyDataSetChanged();
All_Count.setText("总数量:" + mAdapter.allNumber());
All_Price.setText("总价格:" + mAdapter.allPrice());
break;
}
}
private void allCalculation() {
boolean allChecked = mAdapter.isAllChecked();
All_check.setChecked(allChecked);
All_Count.setText("总数量:" + mAdapter.allNumber());
All_Price.setText("总价格:" + mAdapter.allPrice());
}
@Override
public void onSuccess(Object o) {
if (o instanceof MyData) {
mList.addAll(((MyData) o).getResult());
mAdapter.notifyDataSetChanged();
}
}
@Override
public void onError(String error) {
}
}
//网络请求工具类
package soexample.umeng.com.day07_shopping_car_demo.utils;
import com.google.gson.Gson;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import soexample.umeng.com.day07_shopping_car_demo.api.ApiService;
import soexample.umeng.com.day07_shopping_car_demo.url.MyUrls;
public class NetUtils {
private ApiService apiService;
private NetUtils() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.addInterceptor(interceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(MyUrls.BASEURL)
.client(okHttpClient)
//结合Rxjava使用
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
//结合Gson使用
.addConverterFactory(GsonConverterFactory.create())
.build();
apiService = retrofit.create(ApiService.class);
}
private static class NetHolder {
private static final NetUtils netUtils = new NetUtils();
}
public static NetUtils getInstance() {
return NetHolder.netUtils;
}
//没有请求头参数
public void getInfo(String url, final Class cls, final NetCallback callback) {
apiService.getInfoNoParams(url).subscribeOn(Schedulers.io())//被观察者在什么线程上工作
.observeOn(AndroidSchedulers.mainThread())//观察者相应一般都是在主线程
.subscribe(new Observer<ResponseBody>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(ResponseBody responseBody) {
Gson gson = new Gson();
try {
Object object = gson.fromJson(responseBody.string(), cls);
if (callback != null) {
callback.onSuccess(object);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable e) {
if (callback != null) {
callback.onError(e.getMessage());
}
}
@Override
public void onComplete() {
}
});
}
//有请求头参数的
public void getHeaderInfo(String url, Map<String, Object> map, final Class cls, final NetCallback callback) {
apiService.getHeadrInfo(url, map).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<ResponseBody>() {
@Override
public void accept(ResponseBody responseBody) throws Exception {
if (callback != null) {
Gson gson = new Gson();
Object obj = gson.fromJson(responseBody.string(), cls);
callback.onSuccess(obj);
}
}
});
}
public interface NetCallback<T> {
void onSuccess(T t);
void onError(String str);
}
}