Android----仿京东购物车(二级列表,mvp请求数据)

来源:互联网 发布:mac如何剪切复制 编辑:程序博客网 时间:2024/06/06 09:14


下面是购物车列表的简单实现

android中常常要用到ListView,有时也要用到ExpandableListView,如在手机设置中,对于分类有很好的效果,会用ListView的人一定会用ExpandableListView,因为
 ExpandableListView extends ListView的,下面来看个简单的例子
 
 运行效果图:


  1. 一、布局

           MainActivity的布局:

            

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent">    <android.support.v7.widget.RecyclerView        android:id="@+id/recyclerview"        android:layout_width="match_parent"        android:layout_height="385dp"        android:layout_weight="0.77">    </android.support.v7.widget.RecyclerView>    <LinearLayout        android:orientation="horizontal"        android:layout_width="wrap_content"        android:layout_height="wrap_content">        <CheckBox            android:layout_marginLeft="20dp"            android:id="@+id/qunxuan_checkbox"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="全选"/>        <LinearLayout            android:layout_marginLeft="60dp"            android:orientation="vertical"            android:layout_width="wrap_content"            android:layout_height="wrap_content">            <TextView                android:id="@+id/zongjia_text"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="商品的总价:"/>            <TextView                android:id="@+id/zongshu_text"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="商品的总数:"/>        </LinearLayout>        <Button            android:layout_marginLeft="60dp"            android:id="@+id/jiesuan_butn"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="结算"/>    </LinearLayout></LinearLayout>

              子条目的布局

                 

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent">    <LinearLayout        android:orientation="horizontal"        android:layout_width="wrap_content"        android:layout_height="wrap_content">        <CheckBox            android:id="@+id/shangjia_checkbox"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            />        <TextView            android:id="@+id/shangjia_name"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="商家的名字"/>    </LinearLayout>    <LinearLayout        android:orientation="horizontal"        android:layout_width="wrap_content"        android:layout_height="wrap_content">        <CheckBox            android:layout_marginLeft="10dp"            android:layout_gravity="center_vertical"            android:id="@+id/shangpin_checkbox"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <LinearLayout            android:layout_marginLeft="20dp"            android:orientation="vertical"            android:layout_width="wrap_content"            android:layout_height="wrap_content">            <ImageView                android:id="@+id/item_iamgeview"                android:layout_width="50dp"                android:layout_height="50dp"                android:src="@mipmap/ic_launcher"/>            <TextView                android:id="@+id/item_name_text"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="商品的名字"/>            <TextView                android:id="@+id/item_price_text"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="商品的价格"/>            <com.bawei.shop1122application.CustomView                android:id="@+id/customview"                android:layout_width="wrap_content"                android:layout_height="wrap_content"/>        </LinearLayout>        <Button            android:layout_gravity="center_vertical"            android:id="@+id/item_shanchu_butn"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="删除"/>    </LinearLayout></LinearLayout>
                 自定义控件

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal"    android:layout_width="match_parent"    android:layout_height="match_parent">    <Button        android:id="@+id/custom_jian"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="-"/>    <EditText        android:id="@+id/count_edtext"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="1"/>    <Button        android:id="@+id/custom_add"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="+"/></LinearLayout>
       

    二、MVP层

            1,M层接口

                

    public interface IModel {   //定义请求数据成功的方法和失败的方法    public void success(MyBean myBean);    public void failture(Exception e);}
               2.M层类

    public class MyModel {    //请求数据的方法    public void getData(final IModel iModel){        //利用封装请求数据,添加泛型        OkhttpUtils.getInstance().asy(null, "http://120.27.23.105/product/getCarts?uid=100", new AbstractUiCallBack<MyBean>() {            @Override            public void success(MyBean myBean) {                  //调用接口中的方法                iModel.success(myBean);            }            @Override            public void failure(Exception e) {                iModel.failture(e);            }        });    }}
              3、P层

      

    public class MyPresenter {    //实例model和view    private MyModel myModel;    private IView iView;    //注意下边构造器    public MyPresenter(IView iView) {        this.myModel = new MyModel();        this.iView = iView;    }    public void getData(){        myModel.getData(new IModel() {            @Override            public void success(MyBean myBean) {                if (iView!=null){                    iView.success(myBean);                }            }            @Override            public void failture(Exception e) {                if (iView!=null){                    iView.failture(e);                }            }        });    }    /**     * 防止内存泄漏     */    public void detach(){        iView = null;    }}
            

                     4、V层接口

    public interface IView {    //接口里边    //定义请求数据成功的方法和失败的方法    public void success(MyBean myBean);    public void failture(Exception e);}
     


    三、适配器

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{    //上下文和数据源    Context context;    private List<MyBean.DataBean.ListBean> list;    // 存放 商家的id 和 商家名称    private Map<String,String> map = new HashMap<>();    public MyAdapter(Context context) {        this.context = context;    }    //控制商家显示的方法    public void setFirst(List<MyBean.DataBean.ListBean> list){        /*bean中添加一个控制显示的属性isFirst, 1为显示,2为影藏        这个商家是否是第一个出现的,如果是就影藏,如果不是就展示*/        if (list.size()>0){            //数据第一个肯定是显示的            list.get(0).setIsFirst(1);            //就要便利 集合中的商家去判断是不是第一个出现的            for (int i = 1;i<list.size();i++){                //如果当前的显示商家和后一条一样,就影藏                if (list.get(i).getSellerid() == list.get(i-1).getSellerid()){                    //2是影藏                     list.get(i).setIsFirst(2);                }else{                    //1是显示                    list.get(i).setIsFirst(1);                    if (list.get(i).isShangpincheck()){                         list.get(i).setShangjiacheck(list.get(i).isShangpincheck());                    }                }            }        }    }    @Override    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        //创建布局        View view = View.inflate(context,R.layout.item_layout,null);        return new ViewHolder(view);    }    @Override    public void onBindViewHolder(final ViewHolder holder, final int position) {          //填充值        //设置商家的多选框的状态        if (list.get(position).getIsFirst()==1){            //显示商家和商家名字            holder.shangjia_checkbox.setVisibility(View.VISIBLE);            holder.shangjia_name.setVisibility(View.VISIBLE);            //既然显示就给填充值,就需要有一个是否选中了这个多选框的属性,去bean添加            holder.shangjia_checkbox.setChecked(list.get(position).isShangjiacheck());            //设置商家的名字            holder.shangjia_name.setText(map.get(String.valueOf(list.get(position).getSellerid())));        }else{            //隐藏商家和商家名            holder.shangjia_checkbox.setVisibility(View.GONE);            holder.shangjia_name.setVisibility(View.GONE);        }        //设置商品的多选框的状态        holder.shangpin_checkbox.setChecked(list.get(position).isShangpincheck());        //填充图片时,要拆分        String str[] = list.get(position).getImages().split("\\|");        ImageLoader.getInstance().displayImage(str[0],holder.item_iamgeview);//二参为控件        //填充价格        holder.item_price_text.setText(list.get(position).getPrice()+"");        //填充商品名称        holder.item_name_text.setText(list.get(position).getTitle());        //填充自定义控件中输入框的值        holder.customview.setEditText(list.get(position).getNum());        //删除的点击事件        holder.item_shanchu_butn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                list.remove(position);                //删除以后显示第一个                list.remove(position);                setFirst(list);                notifyDataSetChanged();                sum(list);            }        });        //加减号的点击事件        holder.customview.setJiaJian(new CustomView.JiaJian() {            @Override            public void dianji(int count) {                //取到当前的数量                list.get(position).setNum(count);                notifyDataSetChanged();                sum(list);            }        });        //商家的多选框框点击事件        holder.shangjia_checkbox.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                //商家的点击填充值                list.get(position).setShangjiacheck(holder.shangjia_checkbox.isChecked());                //遍历                for (int i=0;i<list.size();i++){                    //如果当前的状态id和数据中的相对应,就说明选中了,商品也要选中                    if (list.get(position).getSellerid()==list.get(i).getSellerid()){                        list.get(i).setShangpincheck(holder.shangjia_checkbox.isChecked());                    }                }                notifyDataSetChanged();                sum(list);            }        });        //商品的多选框点击事件        holder.shangpin_checkbox.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                //商品的点击填充值                list.get(position).setShangpincheck(holder.shangpin_checkbox.isChecked());                //遍历                for (int i=0;i<list.size();i++){                   for (int j=0;j<list.size();j++){                       //如果当前的状态id和数据中的相对应,并且不等于当前商品的点击状态                       if(list.get(i).getSellerid() == list.get(j).getSellerid() && !list.get(j).isShangpincheck()){                           //没有选中                           list.get(i).setShangjiacheck(false);                           break;                       }else {                           //选中                           list.get(i).setShangjiacheck(true);                       }                   }                }                notifyDataSetChanged();                sum(list);            }        });    }    //计算总价的方法,    public void sum(List<MyBean.DataBean.ListBean> list){        int zongshu = 0;        float zongjia  = 0.0f;        boolean allcheck = true;        //循环计算        for (int i = 0;i<list.size();i++){            //如果有选中的商品,就计算            if (list.get(i).isShangpincheck()){                zongshu += list.get(i).getNum();                zongjia += list.get(i).getNum()*list.get(i).getPrice();            }else{                allcheck = false;            }        }        //接口对象调用方法暴露数据        updataUi.gengxin(zongjia+"",zongshu+"",allcheck);    }    //全选的方法    public void selectAll(boolean check){        for(int i=0;i<list.size();i++){            //赋值的            list.get(i).setShangjiacheck(check);            list.get(i).setShangpincheck(check);        }        notifyDataSetChanged();        sum(list);    }    @Override    public int getItemCount() {        return list==null?0:list.size();    }    //把请求到的数据添加到集合中,并跟新    public void addData(MyBean myBean) {        //如果集合是空的,就要先new出集合        if (list==null){            list = new ArrayList<>();        }        //集合不为空的话,就要,添加到集合中        //便利商家,shangjia商家对象        for (MyBean.DataBean shangjia:myBean.getData()){            map.put(shangjia.getSellerid(),shangjia.getSellerName());            //便利出商品            for (int i=0;i<shangjia.getList().size();i++){                this.list.add(shangjia.getList().get(i));            }        }        //添加到view刚进去要显示        setFirst(this.list);        //刷新数据        notifyDataSetChanged();    }    public class ViewHolder extends RecyclerView.ViewHolder {        private final CheckBox shangjia_checkbox;        private final TextView shangjia_name;        private final CheckBox shangpin_checkbox;        private final ImageView item_iamgeview;        private final TextView item_name_text;        private final TextView item_price_text;        private final Button item_shanchu_butn;        private final CustomView customview;        public ViewHolder(View itemView) {            super(itemView);            //找到控件            shangjia_checkbox = itemView.findViewById(R.id.shangjia_checkbox);            shangjia_name = itemView.findViewById(R.id.shangjia_name);            shangpin_checkbox = itemView.findViewById(R.id.shangpin_checkbox);            item_iamgeview = itemView.findViewById(R.id.item_iamgeview);            item_name_text = itemView.findViewById(R.id.item_name_text);            item_price_text = itemView.findViewById(R.id.item_price_text);            customview = itemView.findViewById(R.id.customview);            item_shanchu_butn = itemView.findViewById(R.id.item_shanchu_butn);        }    }    //更新UI界面的接口,mvp模式,View层不做逻辑。。所以,最后回调给V层    public UpdataUi updataUi;    public void setUpdataUi(UpdataUi updataUi) {        this.updataUi = updataUi;    }    public interface UpdataUi{        //需要的参数为,总价格,总数量和是否全选        void gengxin(String zongjia, String  zongshu, boolean allcheck);    }}

    四、Activity

    public class MainActivity extends AppCompatActivity implements IView{    private RecyclerView recyclerview;    private CheckBox qunxuan_checkbox;    private TextView zongjia_text;    private TextView zongshu_text;    private Button jiesuan_butn;    private MyAdapter myAdapter;    private LinearLayoutManager manager;    private MyPresenter myPresenter;    @Override    protected void onCreate(Bundle savedInstanceState){        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //找到控件        recyclerview = (RecyclerView) findViewById(R.id.recyclerview);        qunxuan_checkbox = (CheckBox) findViewById(R.id.qunxuan_checkbox);        zongjia_text = (TextView) findViewById(R.id.zongjia_text);        zongshu_text = (TextView) findViewById(R.id.zongshu_text);        jiesuan_butn = (Button) findViewById(R.id.jiesuan_butn);        //全选        qunxuan_checkbox.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                myAdapter.selectAll(qunxuan_checkbox.isChecked());            }        });        //qunxuan_checkbox.setChecked();        //数据.实例化P        myPresenter = new MyPresenter(this);        myPresenter.getData();        //适配器        myAdapter = new MyAdapter(this);        //创建布局管理器        manager = new LinearLayoutManager(this);        //设置适配器和布局管理器        recyclerview.setAdapter(myAdapter);        recyclerview.setLayoutManager(manager);        //回调接口        myAdapter.setUpdataUi(new MyAdapter.UpdataUi() {            @Override            public void gengxin(String zongjia, String zongshu, boolean allcheck) {                qunxuan_checkbox.setChecked(allcheck);                zongshu_text.setText(zongshu);                zongjia_text.setText(zongjia);            }        });    }    @Override    public void success(MyBean myBean) {        myAdapter.addData(myBean);    }    @Override    public void failture(Exception e) {    }    //防止内存泄漏的方法    @Override    protected void onDestroy() {        super.onDestroy();        //调用P层的方法        myPresenter.detach();    }}


    五、需要用到的ok封装和拦截器

          1、导入OKhttp封装包

           2、添加自定义拦截器

             

    public class LoggingInterceptor implements Interceptor {  @Override public Response intercept(Chain chain) throws IOException {    Request request = chain.request();    long t1 = System.nanoTime();//    logger.info(String.format("Sending request %s on %s%n%s",//        request.url(), chain.connection(), request.headers()));    Response response = chain.proceed(request);    long t2 = System.nanoTime();//    logger.info(String.format("Received response for %s in %.1fms%n%s",//        response.request().url(), (t2 - t1) / 1e6d, response.headers()));    System.out.println("t2 = " + (t2-t1));    return response;  }}
               3.bean,数据来源于网络请求

              4.使用Imageloard请求图片.注意配置和添加网络请求权限

                  

    public class MyApp extends Application{    @Override    public void onCreate() {        super.onCreate();        ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this).build();        ImageLoader.getInstance().init(configuration);    }}
                      

         六、自定义实现类

     

    public class CustomView extends LinearLayout {    private Button custom_jian;    private EditText count_edtext;    private Button custom_add;    //定义输入框的默认值    int mcount = 1;    public CustomView(Context context) {        super(context);    }    public CustomView(Context context, AttributeSet attrs) {        super(context, attrs);        //创建布局        View view = View.inflate(context,R.layout.customview_layout,null);        //找到控件        custom_jian = view.findViewById(R.id.custom_jian);        count_edtext = view.findViewById(R.id.count_edtext);        custom_add = view.findViewById(R.id.custom_add);        //减号的点击事件        custom_jian.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View view) {                //点击之前先拿到输入框里的值                String string = count_edtext.getText().toString().trim();                //转化数据类型                int count = Integer.valueOf(string);                //如果输入框的数据大于1,点击减号的时候,就让其减少一                if (count>1){                    mcount = count-1;                    count_edtext.setText(mcount+"");                }                //接口回调                if (jiaJian!=null){                    jiaJian.dianji(mcount);                }            }        });        //加号的点击事件        custom_add.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View view) {                //点击之前先拿到输入框里的值                String string = count_edtext.getText().toString().trim();                //转化数据类型                int count = Integer.valueOf(string)+1;                //如果输入框的数据大于1,点击减号的时候,就让其减少一                    mcount = count;                    count_edtext.setText(mcount+"");                //接口回调                if (jiaJian!=null){                    jiaJian.dianji(mcount);                }            }        });        //中间输入框内的变化        count_edtext.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {            }            @Override            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {            }            @Override            public void afterTextChanged(Editable editable) {            }        });        addView(view);    }    //给输入框赋值的方法    public void setEditText(int num){        if(count_edtext != null){            count_edtext.setText(num+"");        }    }    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    //加减号的点击事件接口    JiaJian jiaJian;    public void setJiaJian(JiaJian jiaJian) {        this.jiaJian = jiaJian;    }    public interface JiaJian{        public void dianji(int count);    }}
     
阅读全文
0 0
原创粉丝点击