二级列表购物车okhttp(完整版)
2017-12-19 15:37
555 查看
1:首先导入依赖
2:清单列表
3:然后来看下具体结构吧
4bean层
4-1:cratBean是从网上获取的:接口是:https://www.zhaoapi.cn/product/getCarts?uid=3004
4-2countpricebean是用来写方法的:
7model层:
cartmodel:
8:view层
:有5个:cartexpanablelistview,IMainactivity,myadapter,dashapplication,mainactivity
8-1:dashapplication:这个可以和myapp写在一起在清单列表里用name
------------------------------------------------
布局文件啦
activity_main:
相对布局
child_item_layout:
相对布局
线性布局
compile 'com.squareup.okhttp3:okhttp:3.9.0' compile 'com.squareup.okhttp3:logging-interceptor:3.9.0' compile 'com.google.code.gson:gson:2.8.2' compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' compile 'org.greenrobot:eventbus:3.1.1' compile 'com.github.bumptech.glide:glide:3.7.0'
2:清单列表
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
3:然后来看下具体结构吧
4bean层
4-1:cratBean是从网上获取的:接口是:https://www.zhaoapi.cn/product/getCarts?uid=3004
4-2countpricebean是用来写方法的:
public class CountPriceBean { private double price; private int count; public CountPriceBean(double price, int count) { this.price = price; this.count = count; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } } 5net层 5-1:commonUtils
public class CommonUtils { public static final String TAG = "Dash";//sp文件的xml名称 private static SharedPreferences sharedPreferences; public static View inflate(int layoutId) { View view = View.inflate(DashApplication.getAppContext(), layoutId, null); return view; } public static int dip2px(int dip) { //获取像素密度 float density = DashApplication.getAppContext().getResources().getDisplayMetrics().density; // int px = (int) (dip * density + 0.5f);//100.6 return px; } public static int px2dip(int px) { //获取像素密度 float density = DashApplication.getAppContext().getResources().getDisplayMetrics().density; // int dip = (int) (px / density + 0.5f); return dip; } /** * 获取资源中的字符串 * @param stringId * @return */ public static String getString(int stringId) { return DashApplication.getAppContext().getResources().getString(stringId); } public static Drawable getDrawable(int did) { return DashApplication.getAppContext().getResources().getDra 4000 wable(did); } public static int getDimens(int id) { return DashApplication.getAppContext().getResources().getDimensionPixelSize(id); } /** * sp存入字符串类型的值 * @param flag * @param str */ public static void saveSp(String flag, String str) { if (sharedPreferences == null) { sharedPreferences = DashApplication.getAppContext().getSharedPreferences(TAG, DashApplication.getAppContext().MODE_PRIVATE); } SharedPreferences.Editor edit = sharedPreferences.edit(); edit.putString(flag, str); edit.commit(); } public static String getSp(String flag) { if (sharedPreferences == null) { sharedPreferences = DashApplication.getAppContext().getSharedPreferences(TAG, DashApplication.getAppContext().MODE_PRIVATE); } return sharedPreferences.getString(flag, ""); } public static boolean getBoolean(String tag) { if (sharedPreferences == null) { sharedPreferences = DashApplication.getAppContext().getSharedPreferences(TAG, DashApplication.getAppContext().MODE_PRIVATE); } return sharedPreferences.getBoolean(tag, false); } public static void putBoolean(String tag, boolean content) { if (sharedPreferences == null) { sharedPreferences = DashApplication.getAppContext().getSharedPreferences(TAG, DashApplication.getAppContext().MODE_PRIVATE); } SharedPreferences.Editor edit = sharedPreferences.edit(); edit.putBoolean(tag, content); edit.commit(); } /** * 清除sp数据 * @param tag */ public static void clearSp(String tag) { if (sharedPreferences == null) { sharedPreferences = DashApplication.getAppContext().getSharedPreferences(TAG, DashApplication.getAppContext().MODE_PRIVATE); } SharedPreferences.Editor edit = sharedPreferences.edit(); edit.remove(tag); edit.commit(); } /** * 自己写的运行在主线程的方法 * 如果是主线程,执行任务,否则使用handler发送到主线程中去执行 * * * @param runable */ public static void runOnUIThread(Runnable runable) { //先判断当前属于子线程还是主线程 if (android.os.Process.myTid() == DashApplication.getMainThreadId()) { runable.run(); } else { //子线程 DashApplication.getAppHanler().post(runable); } } } 5-2:okhttp3util:
public class OkHttp3Util { private static OkHttpClient okHttpClient = null; private OkHttp3Util() { } public static OkHttpClient getInstance() { if (okHttpClient == null) { //加同步安全 synchronized (OkHttp3Util.class) { if (okHttpClient == null) { //okhttp可以缓存数据....指定缓存路径 File sdcache = new File(Environment.getExternalStorageDirectory(), "cache"); //指定缓存大小 int cacheSize = 10 * 1024 * 1024; okHttpClient = new OkHttpClient.Builder()//构建器 .connectTimeout(15, TimeUnit.SECONDS)//连接超时 .writeTimeout(20, TimeUnit.SECONDS)//写入超时 .readTimeout(20, TimeUnit.SECONDS)//读取超时 .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize))//设置缓存 .build(); } } } return okHttpClient; } /** * get请求 * 参数1 url * 参数2 回调Callback */ public static void doGet(String oldUrl, Callback callback) { //要添加的公共参数...map Map<String,String> map = new HashMap<>(); map.put("source","android"); StringBuilder stringBuilder = new StringBuilder();//创建一个stringBuilder stringBuilder.append(oldUrl); if (oldUrl.contains("?")){ //?在最后面....2类型 if (oldUrl.indexOf("?") == oldUrl.length()-1){ }else { //3类型...拼接上& stringBuilder.append("&"); } }else { //不包含? 属于1类型,,,先拼接上?号 stringBuilder.append("?"); } //添加公共参数.... for (Map.Entry<String,String> entry: map.entrySet()) { //拼接 stringBuilder.append(entry.getKey()) .append("=") .append(entry.getValue()) .append("&"); } //删掉最后一个&符号 if (stringBuilder.indexOf("&") != -1){ stringBuilder.deleteCharAt(stringBuilder.lastIndexOf("&")); } String newUrl = stringBuilder.toString();//新的路径 //创建OkHttpClient请求对象 OkHttpClient okHttpClient = getInstance(); //创建Request Request request = new Re 227e8 quest.Builder().url(newUrl).build(); //得到Call对象 Call call = okHttpClient.newCall(request); //执行异步请求 call.enqueue(callback); } public static void doPost(String url, Map<String, String> params, Callback callback) { //要添加的公共参数...map Map<String,String> map = new HashMap<>(); map.put("source","android"); //创建OkHttpClient请求对象 OkHttpClient okHttpClient = getInstance(); //3.x版本post请求换成FormBody 封装键值对参数 FormBody.Builder builder = new FormBody.Builder(); //遍历集合 for (String key : params.keySet()) { builder.add(key, params.get(key)); } //添加公共参数 for (Map.Entry<String,String> entry: map.entrySet()) { builder.add(entry.getKey(),entry.getValue()); } //创建Request Request request = new Request.Builder().url(url).post(builder.build()).build(); Call call = okHttpClient.newCall(request); call.enqueue(callback); } public static void uploadFile(String url, File file, String fileName,Map<String,String> params) { //创建OkHttpClient请求对象 OkHttpClient okHttpClient = getInstance(); MultipartBody.Builder builder = new MultipartBody.Builder(); builder.setType(MultipartBody.FORM); //参数 if (params != null){ for (String key : params.keySet()){ builder.addFormDataPart(key,params.get(key)); } } //文件...参数name指的是请求路径中所接受的参数...如果路径接收参数键值是fileeeee,此处应该改变 builder.addFormDataPart("file",fileName,RequestBody.create(MediaType.parse("application/octet-stream"),file)); //构建 MultipartBody multipartBody = builder.build(); //创建Request Request request = new Request.Builder().url(url).post(multipartBody).build(); //得到Call Call call = okHttpClient.newCall(request); //执行请求 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e("upload",e.getLocalizedMessage()); } @Override public void onResponse(Call call, Response response) throws IOException { //上传成功回调 目前不需要处理 if (response.isSuccessful()){ String s = response.body().string(); Log.e("upload","上传--"+s); } } }); } /** * Post请求发送JSON数据....{"name":"zhangsan","pwd":"123456"} * 参数一:请求Url * 参数二:请求的JSON * 参数三:请求回调 */ public static void doPostJson(String url, String jsonParams, Callback callback) { RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams); Request request = new Request.Builder().url(url).post(requestBody).build(); Call call = getInstance().newCall(request); call.enqueue(callback); } /** * 下载文件 以流的形式把apk写入的指定文件 得到file后进行安装 * 参数er:请求Url * 参数san:保存文件的文件夹....download */ public static void download(final Activity context, final String url, final String saveDir) { Request request = new Request.Builder().url(url).build(); Call call = getInstance().newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { //com.orhanobut.logger.Logger.e(e.getLocalizedMessage()); } @Override public void onResponse(Call call, final Response response) throws IOException { InputStream is = null; byte[] buf = new byte[2048]; int len = 0; FileOutputStream fos = null; try { is = response.body().byteStream();//以字节流的形式拿回响应实体内容 //apk保存路径 final String fileDir = isExistDir(saveDir); //文件 File file = new File(fileDir, getNameFromUrl(url)); fos = new FileOutputStream(file); while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); } fos.flush(); context.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(context, "下载成功:" + fileDir + "," + getNameFromUrl(url), Toast.LENGTH_SHORT).show(); } }); //apk下载完成后 调用系统的安装方法 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); context.startActivity(intent); } catch (IOException e) { e.printStackTrace(); } finally { if (is != null) is.close(); if (fos != null) fos.close(); } } }); } /** * 判断下载目录是否存在......并返回绝对路径 * * @param saveDir * @return * @throws IOException */ public static String isExistDir(String saveDir) throws IOException { // 下载位置 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { File downloadFile = new File(Environment.getExternalStorageDirectory(), saveDir); if (!downloadFile.mkdirs()) { downloadFile.createNewFile(); } String savePath = downloadFile.getAbsolutePath(); Log.e("savePath", savePath); return savePath; } return null; } /** * @param url * @return 从下载连接中解析出文件名 */ private static String getNameFromUrl(String url) { return url.substring(url.lastIndexOf("/") + 1); } /** * 公共参数拦截器 */ private static class CommonParamsInterceptor implements Interceptor{ //拦截的方法 @Override public Response intercept(Chain chain) throws IOException { //获取到请求 Request request = chain.request(); //获取请求的方式 String method = request.method(); //获取请求的路径 String oldUrl = request.url().toString(); Log.e("---拦截器",request.url()+"---"+request.method()+"--"+request.header("User-agent")); //要添加的公共参数...map Map<String,String> map = new HashMap<>(); map.put("source","android"); if ("GET".equals(method)){ // 1.http://www.baoidu.com/login --------? key=value&key=value // 2.http://www.baoidu.com/login? --------- key=value&key=value // 3.http://www.baoidu.com/login?mobile=11111 -----&key=value&key=value StringBuilder stringBuilder = new StringBuilder();//创建一个stringBuilder stringBuilder.append(oldUrl); if (oldUrl.contains("?")){ //?在最后面....2类型 if (oldUrl.indexOf("?") == oldUrl.length()-1){ }else { //3类型...拼接上& stringBuilder.append("&"); } }else { //不包含? 属于1类型,,,先拼接上?号 stringBuilder.append("?"); } //添加公共参数.... for (Map.Entry<String,String> entry: map.entrySet()) { //拼接 stringBuilder.append(entry.getKey()) .append("=") .append(entry.getValue()) .append("&"); } //删掉最后一个&符号 if (stringBuilder.indexOf("&") != -1){ stringBuilder.deleteCharAt(stringBuilder.lastIndexOf("&")); } String newUrl = stringBuilder.toString();//新的路径 //拿着新的路径重新构建请求 request = request.newBuilder() .url(newUrl) .build(); }else if ("POST".equals(method)){ //先获取到老的请求的实体内容 RequestBody oldRequestBody = request.body();//....之前的请求参数,,,需要放到新的请求实体内容中去 //如果请求调用的是上面doPost方法 if (oldRequestBody instanceof FormBody){ FormBody oldBody = (FormBody) oldRequestBody; //构建一个新的请求实体内容 FormBody.Builder builder = new FormBody.Builder(); //1.添加老的参数 for (int i=0;i<oldBody.size();i++){ builder.add(oldBody.name(i),oldBody.value(i)); } //2.添加公共参数 for (Map.Entry<String,String> entry:map.entrySet()) { builder.add(entry.getKey(),entry.getValue()); } FormBody newBody = builder.build();//新的请求实体内容 //构建一个新的请求 request = request.newBuilder() .url(oldUrl) .post(newBody) .build(); } } Response response = chain.proceed(request); return response; } } } 6:present层: 6-1:ICartPresenter
public interface ICartPresenter { void getSuccessCartJson(String json); } 6-2:cartPreaenter:
public class CartPresenter implements ICartPresenter{ private final CartModel cartModel; private IMainActivity iMainActivity; public CartPresenter(IMainActivity iMainActivity) { this.iMainActivity = iMainActivity; cartModel = new CartModel(this); } public void getCartData(String cartUrl) { cartModel.getCartData(cartUrl); } @Override public void getSuccessCartJson(String json) { //回调给view iMainActivity.getSuccessCartData(json); } }
7model层:
cartmodel:
public class CartModel { private ICartPresenter iCartPresenter; public CartModel(ICartPresenter iCartPresenter) { this.iCartPresenter = iCartPresenter; } public void getCartData(final String cartUrl) { //获取数据 OkHttp3Util.doGet(cartUrl, new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e(cartUrl,e.getLocalizedMessage()); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()){ final String json = response.body().string(); //返回数据到主线程 CommonUtils.runOnUIThread(new Runnable() { @Override public void run() { iCartPresenter.getSuccessCartJson(json); } }); } } }); } }
8:view层
:有5个:cartexpanablelistview,IMainactivity,myadapter,dashapplication,mainactivity
8-1:dashapplication:这个可以和myapp写在一起在清单列表里用name
public class DashApplication extends Application { private static Context context; private static Handler handler; private static int mainId; public static boolean isLoginSuccess;//是否已经登录的状态 @Override public void onCreate() { super.onCreate(); //关于context----http://blog.csdn.net/lmj623565791/article/details/40481055 context = getApplicationContext(); //初始化handler handler = new Handler(); //主线程的id mainId = Process.myTid(); } /** * 对外提供了context * @return */ public static Context getAppContext() { return context; } /** * 得到全局的handler * @return */ public static Handler getAppHanler() { return handler; } /** * 获取主线程id * @return */ public static int getMainThreadId() { return mainId; } }
8-2 :cartexpanablelistview
public class CartExpanableListview extends ExpandableListView { public CartExpanableListview(Context context) { super(context); } public CartExpanableListview(Context context, AttributeSet attrs) { super(context, attrs); } public CartExpanableListview(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, height); } }
8-3:IMainactivity
public interface IMainActivity { void getSuccessCartData(String json); }
8-4:myadapter
public class MyAdapter extends BaseExpandableListAdapter{ private Handler handler; private Context context; private List<CartBean.DataBean> listGroup; private List<List<CartBean.DataBean.ListBean>> listChilds; public MyAdapter(Context context, List<CartBean.DataBean> listGroup, List<List<CartBean.DataBean.ListBean>> listChilds, Handler handler) { this.context = context; this.listGroup = listGroup; this.listChilds = listChilds; this.handler = handler; } @Override public int getGroupCount() { return listGroup.size(); } @Override public int getChildrenCount(int i) { return listChilds.get(i).size(); } @Override public Object getGroup(int i) { return listGroup.get(i); } @Override public Object getChild(int i, int i1) { return listChilds.get(i).get(i1); } @Override public long getGroupId(int i) { return i; } @Override public long getChildId(int i, int i1) { return i1; } @Override public boolean hasStableIds() { return true; } @Override public View getGroupView(final int i, boolean b, View view, ViewGroup viewGroup) { GroupHolder holder; if (view==null){ view = View.inflate(context, R.layout.group_item_layout, null); holder=new GroupHolder(); holder.check_group=view.findViewById(R.id.check_group); holder.text_group=view.findViewById(R.id.text_group); view.setTag(holder); }else{ holder= (GroupHolder) view.getTag(); } final CartBean.DataBean dataBean=listGroup.get(i); //赋值 holder.check_group.setChecked(dataBean.isGroupChecked()); holder.text_group.setText(dataBean.getSellerName()); //设置点击事件 holder.check_group.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //改变当前一级选中状态 dataBean.setGroupChecked(!dataBean.isGroupChecked()); //根据当前一级状态,改变改组里耳机列表的状态 changeChildState(i,dataBean.isGroupChecked()); //通过判断所有一级组是否选中,来决定是否全部选中 changeAllState(isAllGroupChecked()); //发送价格个数量 sendPriceAndCount(); //刷新适配器 notifyDataSetChanged(); } }); return view; } /** * 根据所有一级列表是否选中,确定外面的全选是否选中 * @param allGroupChecked */ private void changeAllState(boolean allGroupChecked) { Message msg = Message.obtain(); msg.what =1; msg.obj = allGroupChecked; handler.sendMessage(msg); } /** * 所有的一级列表是否选中 * @return */ private boolean isAllGroupChecked() { for (int i=0;i<listGroup.size();i++){ if (! listGroup.get(i).isGroupChecked()){ return false; } } return true; } /** * 根据当前一级列表的状态,,,改变当前组中所有二级列表的状态 * @param groupPosition * @param groupChecked */ private void changeChildState(int groupPosition, boolean groupChecked) { List<CartBean.DataBean.ListBean> listBeans = listChilds.get(groupPosition); for (int i=0;i<listBeans.size();i++){ listBeans.get(i).setSelected(groupChecked? 1:0); } } @Override public View getChildView(final int i, int i1, boolean b, View view, ViewGroup viewGroup) { ChildHolder holder; if (view==null){ view = View.inflate(context, R.layout.child_item_layout, null); holder=new ChildHolder(); holder.text_add = view.findViewById(R.id.text_add); holder.text_num = view.findViewById(R.id.text_num); holder.text_jian = view.findViewById(R.id.text_jian); holder.text_title = view.findViewById(R.id.text_title); holder.text_price = view.findViewById(R.id.text_price); holder.image_good = view.findViewById(R.id.image_good); holder.check_child = view.findViewById(R.id.check_child); view.setTag(holder); }else{ holder= (ChildHolder) view.getTag(); } final CartBean.DataBean.ListBean listBean=listChilds.get(i).get(i1); holder.text_num.setText(listBean.getNum()+""); holder.text_price.setText("$"+listBean.getPrice()); holder.text_title.setText(listBean.getTitle()); //设置checkbox为选中状态 holder.check_child.setChecked(listBean.getSelected()==0? false:true); Glide.with(context).load(listBean.getImages().split("\\|")[0]).into(holder.image_good); //设置点击事件 holder.check_child.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //点击改变当前子条目状态...实际是改变当前数据..刷新适配器 listBean.setSelected(listBean.getSellerid()==0? 1:0); //发送价钱的数量给界面 sendPriceAndCount(); //判断当前子条目是否选中 if (listBean.getSelected()==1){ //判断一下当前组中所有的子条目是否全部选中 if (isAllChildSelected(i)){ //如果全部选中改变当前组状态 changeGroupState(i,true); //确定是否改变全选 changeAllState(isAllGroupChecked()); } }else { //如果没有选中改变一下当前组的状态 changeGroupState(i,false); //.确定是否改变全选 changeAllState(isAllGroupChecked()); } notifyDataSetChanged(); } }); //加号: holder.text_add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //改变当前位置 中商品的数量 listBean.setNum(listBean.getNum()+1); //判断一下是否选中...计算价格数量 if (listBean.getSelected() == 1){ sendPriceAndCount(); } // notifyDataSetChanged(); } }); //减号 holder.text_jian.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int num = listBean.getNum(); if (num == 1){ return; } listBean.setNum(num -1); //判断是否选中 if (listBean.getSelected() == 1){ sendPriceAndCount(); } notifyDataSetChanged(); } }); return view; } /** * 改变当前组的状态 * @param groupPosition * @param b */ private void changeGroupState(int groupPosition, boolean b) { listGroup.get(groupPosition).setGroupChecked(b); } /** * 判断当前组中所有的二级是否选中 * @param groupPosition * @return */ private boolean isAllChildSelected(int groupPosition) { List<CartBean.DataBean.ListBean> listBeans = listChilds.get(groupPosition); for (int i=0;i<listBeans.size();i++){ if (listBeans.get(i).getSelected() == 0){ return false; } } return true; } @Override public boolean isChildSelectable(int i, int i1) { return true;//子条目是否可以点击 } /** * 设置是否全选 * @param checked */ public void setIfCheckAll(boolean checked) { for (int i = 0;i<listGroup.size();i++){ CartBean.DataBean dataBean = listGroup.get(i); //设置组上面的checkBox是否选中 dataBean.setGroupChecked(checked); List<CartBean.DataBean.ListBean> listBeans = dataBean.getList(); for (int j = 0; j< listBeans.size(); j++){ //改变是否选中的状态...数据应该变的是 listBeans.get(j).setSelected(checked? 1:0); } } //计算价钱和数量并且发送到mainActivity显示 sendPriceAndCount(); //刷新适配器 notifyDataSetChanged(); } /** * 计算总价和数量,,,发送显示 */ private void sendPriceAndCount() { double price = 0; int count = 0; for (int i=0;i<listGroup.size();i++){ List<CartBean.DataBean.ListBean> listBeans = listGroup.get(i).getList(); for (int j = 0;j<listBeans.size();j++){ CartBean.DataBean.ListBean listBean = listBeans.get(j); if (listBean.getSelected()==1){ price += listBean.getPrice()* listBean.getNum(); count += listBean.getNum(); } } } CountPriceBean countPriceBean = new CountPriceBean(price, count); //显示到activity页面 Message msg = Message.obtain(); msg.what = 0; msg.obj = countPriceBean; handler.sendMessage(msg); } private class GroupHolder{ CheckBox check_group; TextView text_group; } private class ChildHolder{ CheckBox check_child; ImageView image_good; TextView text_title; TextView text_price; TextView text_jian; TextView text_num; TextView text_add; } }8-5:mainactivity
public class MainActivity extends AppCompatActivity implements IMainActivity,View.OnClickListener{ private CartExpanableListview expanableListview; private String cartUrl = "https://www.zhaoapi.cn/product/getCarts?uid=3004"; private CartPresenter cartPresenter; private Gson gson; private MyAdapter myAdapter; private CheckBox check_all; private TextView text_total; private TextView text_buy; private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { if (msg.what == 0){ CountPriceBean countPriceBean = (CountPriceBean) msg.obj; //设置 text_total.setText("合计:¥"+countPriceBean.getPrice()); text_buy.setText("去结算("+countPriceBean.getCount()+")"); }else if (msg.what == 1){//改变全选 boolean flag = (boolean) msg.obj; check_all.setChecked(flag); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); check_all = (CheckBox) findViewById(R.id.check_all); text_total = (TextView) findViewById(R.id.text_total); text_buy = (TextView) findViewById(R.id.text_buy); expanableListview = (CartExpanableListview) findViewById(R.id.expanable_listview); //去掉默认的指示器 expanableListview.setGroupIndicator(null); cartPresenter = new CartPresenter(this); gson = new Gson(); //全选:...点击事件 check_all.setOnClickListener(this); } @Override protected void onResume() { super.onResume(); //请求数据 cartPresenter.getCartData(cartUrl); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.check_all: myAdapter.setIfCheckAll(check_all.isChecked()); break; } } @Override public void getSuccessCartData(String json) { //解析数据 CartBean cartBean=gson.fromJson(json,CartBean.class); //一个是一级标题的数据 List<CartBean.DataBean> listGroup =cartBean.getData(); //所有子条目的数据 List<List<CartBean.DataBean.ListBean>> listChilds = new ArrayList<>(); for (int i=0;i<listGroup.size();i++){ listChilds.add(listGroup.get(i).getList()); } //设置适配器 myAdapter = new MyAdapter(MainActivity.this, listGroup, listChilds,handler); expanableListview.setAdapter(myAdapter); //展开所有 for (int i=0;i<listGroup.size();i++){ expanableListview.expandGroup(i); } } }
------------------------------------------------
布局文件啦
activity_main:
相对布局
<ScrollView android:layout_above="@+id/linear_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.bwie.buycar.view.CartExpanableListview android:id="@+id/expanable_listview" android:layout_width="match_parent" android:layout_height="wrap_content"> </com.bwie.buycar.view.CartExpanableListview> <LinearLayout android:orientation="vertical" android:background="#00ff00" android:layout_width="match_parent" android:layout_height="500dp"> </LinearLayout> </LinearLayout> </ScrollView> <LinearLayout android:id="@+id/linear_layout" android:layout_alignParentBottom="true" android:gravity="center_vertical" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="50dp"> <CheckBox android:layout_marginLeft="10dp" android:button="@null" android:background="@drawable/check_box_selector" android:id="@+id/check_all" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_total" android:text="合计:¥0.00" android:layout_weight="2" android:layout_width="0dp" android:layout_height="wrap_content" /> <TextView android:text="去结算(0)" android:background="#ff0000" android:textColor="#ffffff" android:gravity="center" android:id="@+id/text_buy" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" /> </LinearLayout>
child_item_layout:
相对布局
<CheckBox android:layout_centerVertical="true" android:id="@+id/check_child" android:button="@null" android:background="@drawable/check_box_selector" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:id="@+id/image_good" android:layout_centerVertical="true" android:layout_toRightOf="@+id/check_child" android:layout_marginLeft="10dp" android:layout_width="80dp" android:layout_height="80dp" /> <TextView android:id="@+id/text_title" android:layout_toRightOf="@+id/image_good" android:layout_marginLeft="10dp" android:layout_alignTop="@+id/image_good" android:maxLines="2" android:minLines="2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_price" android:layout_toRightOf="@+id/image_good" android:layout_marginLeft="10dp" android:layout_alignBottom="@+id/image_good" android:text="¥99.99" android:textColor="#ff0000" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <LinearLayout android:layout_alignParentRight="true" android:layout_alignBottom="@+id/image_good" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/text_jian" android:text="一" android:padding="5dp" android:background="@drawable/bian_kuang_line" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:gravity="center" android:id="@+id/text_num" android:paddingLeft="10dp" android:paddingRight="10dp" android:background="@drawable/bian_kuang_line" android:layout_width="wrap_content" android:layout_height="match_parent" /> <TextView android:id="@+id/text_add" android:text="十" android:padding="5dp" android:background="@drawable/bian_kuang_line" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>grop_item_layout:
线性布局
<CheckBox android:button="@null" android:background="@drawable/check_box_selector" android:id="@+id/check_group" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_marginLeft="10dp" android:text="京东自营" android:id="@+id/text_group" android:layout_width="wrap_content" android:layout_height="wrap_content" />
相关文章推荐
- 使用MVP,recycleview,okhttp生成二级购物车。
- 购物车的二级列表全选单选
- 一级列表购物车完整版
- 二级列表实现购物车功能
- 二级列表ExpandableListView 仿京东购物车
- 购物车需要的内容(二级列表、封装工具类)
- 二级列表仿购物车
- 二级列表实现购物车添加购物车
- 使用recycleview,okhttp实现购物车
- 二级列表实现购物车的效果
- (安卓) 购物车二级列表,计算和全反选 以及 EventBus(消息传递)
- 组合属性动画:缩放、渐变 平移和旋转+ImageLoader加载图片+MVP+OKhttp+拦截器+请求网络数据二级列表购物车
- Andriod购物车实现二级列表(MVP)
- 购物车的二级列表适配器
- 二级列表RecyclerView购物车
- Android_二级列表购物车之增删改查,全选反选,加减器,价钱数量计算
- 二级列表购物车的全选反选
- android二级列表购物车
- Android用MVP实现的二级列表购物车
- 使用ExpandListView二级列表实现购物车