【Android】实现简易购物车功能(附源码)

news2024/12/26 4:09:00

先上结果:
在这里插入图片描述

代码:

首先引入图片加载:

implementation 'com.github.bumptech.glide:glide:4.15.1'

在这里插入图片描述
配置权限清单:

    <!-- 网络权限 -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

在这里插入图片描述

页面布局:activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="#2196F3">
        <TextView
            android:id="@+id/personalCenterText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="购物车"
            android:textColor="#ffffff"
            android:textSize="24sp" />

        <TextView
            android:id="@+id/edit"
            android:text="编辑"
            android:textColor="@color/white"
            android:textSize="24sp"
            android:layout_marginEnd="10dp"
            android:layout_centerVertical="true"
            android:layout_alignParentEnd="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </RelativeLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="0dp"/>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">
        <CheckBox
            android:id="@+id/allSelect"
            android:text="全选"
            android:layout_centerVertical="true"
            android:textColor="@color/colorAccent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/total"
            android:textSize="20sp"
            android:text="合计0.00¥"
            android:textColor="@color/colorAccent"
            android:layout_centerVertical="true"
            android:layout_toStartOf="@id/pay"
            android:layout_marginEnd="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/pay"
            android:text="结算"
            android:textColor="@color/white"
            android:background="@drawable/button_red"
            android:layout_width="100dp"
            android:layout_alignParentEnd="true"
            android:layout_height="wrap_content"/>
    </RelativeLayout>

</LinearLayout>

条目布局:item_cart.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="100dp">
    <CheckBox
        android:id="@+id/checkbox"
        android:layout_centerVertical="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <ImageView
        android:id="@+id/cover"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_margin="10dp"
        android:layout_toEndOf="@id/checkbox" />
    <LinearLayout
        android:layout_toEndOf="@id/cover"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            android:textSize="18sp"
            android:textColor="@color/black"
            android:maxLines="2"
            android:ellipsize="end"
            android:layout_marginTop="5dp" />
        <TextView
            android:id="@+id/price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=""
            android:textColor="#D32F2F"
            android:textStyle="bold"
            android:layout_marginTop="5dp" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/view_number"
        android:layout_width="wrap_content"
        android:layout_height="23dp"
        android:background="@drawable/shape_cart_item_add_cut_border"
        android:divider="@drawable/shape_divider_1_v"
        android:orientation="horizontal"
        android:showDividers="middle"
        android:layout_marginBottom="10dp"
        android:layout_marginEnd="10dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true">

        <TextView
            android:id="@+id/tv_reduce"
            android:layout_width="27dp"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="-"
            android:textColor="#676767"
            android:textSize="15sp"/>

        <TextView
            android:id="@+id/tv_num"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:minWidth="40dp"
            android:paddingHorizontal="12dp"
            android:singleLine="true"
            android:text="1"
            android:textColor="#676767"
            android:textSize="15sp"/>

        <TextView
            android:id="@+id/tv_add"
            android:layout_width="27dp"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="+"
            android:textColor="#676767"
            android:textSize="15sp"/>
    </LinearLayout>
</RelativeLayout>

资源文件:shape_cart_item_add_cut_border.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle"
       android:visible="true">
    <!-- 描边,边框 -->
    <stroke
        android:width="1px"
        android:color="#E0E0E0"/><!--dashGap虚线段的间距、dashWidth虚线段的长度-->
</shape>

shape_divider_1_v.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle"
       android:visible="true">
    <size
        android:width="1px"/><!-- 宽度和高度 -->
    <!-- 填充 -->
    <solid
        android:color="#E0E0E0"/><!-- 填充的颜色 -->
</shape>

适配器:CartAdapter

public class CartAdapter extends RecyclerView.Adapter<CartAdapter.Holder> {
    private final List<CartBean> list;
    private final Context context;
    private final List<CartBean> selects=new ArrayList<>();

    public CartAdapter(List<CartBean> list, Context context) {
        this.list = list;
        this.context = context;
    }

    @NonNull
    @Override
    public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.item_cart,null,false);
        return new Holder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull Holder holder, int position) {
        CartBean cartBean =list.get(position);
        holder.name.setText(cartBean.getName());
        holder.number.setText(String.valueOf(cartBean.getNumber()));
        holder.price.setText(String.format("%1$.2f¥", cartBean.getPrice()));
        holder.reduce.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int n;
                n = Integer.parseInt(holder.number.getText().toString());
                if (n >1){
                    n = n -1;
                    holder.number.setText(String.valueOf(n));
                    cartBean.setNumber(n);
                }
                else {
                    Toast.makeText(context,"最少选择一件",Toast.LENGTH_SHORT).show();
                }
                updateItem();
            }
        });
        holder.add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int n;
                n = Integer.parseInt(holder.number.getText().toString());
                n = n + 1;
                cartBean.setNumber(n);
                holder.number.setText(String.valueOf(n));
                updateItem();
            }
        });
        holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                cartBean.setSelect(b);
                updateItem();
            }
        });
        holder.checkBox.setChecked(cartBean.isSelect());
        Glide.with(context).load(cartBean.getCover()).into(holder.cover);
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public static class Holder extends RecyclerView.ViewHolder{
        CheckBox checkBox;
        ImageView cover;
        TextView name,number,reduce,add,price;
        public Holder(@NonNull View itemView) {
            super(itemView);
            checkBox=itemView.findViewById(R.id.checkbox);
            cover=itemView.findViewById(R.id.cover);
            name=itemView.findViewById(R.id.name);
            number=itemView.findViewById(R.id.tv_num);
            reduce=itemView.findViewById(R.id.tv_reduce);
            add=itemView.findViewById(R.id.tv_add);
            price=itemView.findViewById(R.id.price);
        }
    }
    private void updateItem(){
        selects.clear();
        for (CartBean cartBean:list){
            if (cartBean.isSelect()){
                selects.add(cartBean);
            }
        }
        onChange.change(selects);
    }
    public OnChange onChange;

    public void setOnChange(OnChange onChange) {
        this.onChange = onChange;
    }

    public List<CartBean> getSelects() {
        return selects;
    }
    //条目改变-接口回调
    public interface OnChange{
        void change(List<CartBean> selects);
    }
}

bean类:CartBean

public class CartBean {
    private String name;
    private String cover;
    private boolean isSelect;
    private int number;
    private double price;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCover() {
        return cover;
    }

    public void setCover(String cover) {
        this.cover = cover;
    }

    public boolean isSelect() {
        return isSelect;
    }

    public void setSelect(boolean select) {
        isSelect = select;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public CartBean(String name, String cover, boolean isSelect, int number, double price) {
        this.name = name;
        this.cover = cover;
        this.isSelect = isSelect;
        this.number = number;
        this.price = price;
    }

    @Override
    public String toString() {
        return "CartBean{" +
                "name='" + name + '\'' +
                ", cover='" + cover + '\'' +
                ", isSelect=" + isSelect +
                ", number=" + number +
                ", price=" + price +
                '}';
    }
}

源码

github:https://github.com/panzhusheng/CartDemo
gitee:https://gitee.com/pan-zs/cart-demo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1418387.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu22.04@laptop安装配置VNC服务端

ubuntu22.04laptop安装&配置VNC服务端 1. 源由2. 系统安装3. VNC安装3.1 系统更新3.2 lightdm安装3.3 x11vnc安装3.4 x11vnc配置3.5 x11vnc自启动3.6 x11vnc状态查询 4. 演示视频 1. 源由 最近系统搞TensorFlow, OpenCV, Python&#xff0c;折腾各种环境&#xff0c;把系统…

数据库管理-第139期 做大还是做小-Oracle名称哪些事(20240125)

数据库管理139期 2024-01-25 第139期 做大还是做小-Oracle名称哪些事&#xff08;20240125&#xff09;1 问题2 排查3 扩展总结 第139期 做大还是做小-Oracle名称哪些事&#xff08;20240125&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&#xff09; Oracle A…

【备战蓝桥杯】——循环结构

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-bFHV3Dz5xMe6d3NB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

Leetcode刷题笔记题解(C++):1114. 按序打印(多线程)

思路&#xff1a; 保证A,B,C三个线程的顺序不会变&#xff0c;即优先级顺序的问题 A,B需要资源1&#xff0c;B,C需要资源2 A先占用资源1和资源2&#xff0c;A线程完了之后释放资源1不释放资源2&#xff0c;然后B线程占用资源1&#xff0c;A线程完了之后释放资源1和资源2&…

【极数系列】Flink配置参数如何获取?(06)

文章目录 gitee码云地址简介概述01 配置值来自.properties文件1.通过路径读取2.通过文件流读取3.通过IO流读取 02 配置值来自命令行03 配置来自系统属性04 注册以及使用全局变量05 Flink获取参数值Demo1.项目结构2.pom.xml文件如下3.配置文件4.项目主类5.运行查看相关日志 gite…

D6212——由八路达林顿管 阵列和 H 桥驱动电路两个单元组成,可用于驱动步进电机等产品上

D6212是专为安防摄像头系统设计的驱动电路&#xff0c;电路由八路达林顿管 阵列和 H 桥驱动电路两个单元组成。八路达林顿管阵列均带有续流二极 管&#xff0c;可用于驱动步进电机&#xff1b;H 桥驱动电路单元可以直接驱动IR-CUT。单个 达林顿管在输入电压低至 1.8V 状态下支持…

SQL中实现行列转换

目录 方法一&#xff1a;sum case when 方法二&#xff1a;sum if 方法三&#xff1a;pivot 现在有一张表class_gender&#xff0c;内容如下&#xff1a; classgender一年级女一年级女一年级男一年级男二年级女二年级女二年级男 现在我们要根据上表&#xff0c;统计得到下…

spring boot学习第八篇:操作elastic search的索引和索引中的数据

前提参考&#xff1a;elastic search入门-CSDN博客 前提说明&#xff1a;已经安装好了elastic search 7.x版本&#xff0c;我的es版本是7.11.1 1、 pom.xml文件内容如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns&q…

深分页怎么导致索引失效了?提供6种优化的方案!

深分页怎么导致索引失效了&#xff1f;提供6种优化的方案&#xff01; 上篇文章说到索引失效的几种规则&#xff0c;其中就有包括 深分页回表太多导致索引失效 的场景 本篇文章来聊聊深分页场景中的问题并提供几种优化方案&#xff0c;以下是本篇文章的思维导图&#xff1a; …

go学习之air库的使用

首先下载air库 go install github.com/cosmtrek/air之后你需要去找到库下载的地方&#xff0c;若使用的是go mod可以使用命令 go env GOPATH找到下载库的位置 进入后&#xff0c;有bin&#xff0c;pkg目录&#xff0c;进入bin目录&#xff0c;你能看到air.exe文件 这时候将此…

数据结构(队列Queue)

文章目录 一、队列1、队列的定义2、队列的顺序实现2.1、初始化2.2、入队2.3、出队2.4、查找2.5、判断队列 满/空 3、队列的链式实现3.1、初始化3.2、入队3.3、出队 4、双端队列 一、队列 1、队列的定义 2、队列的顺序实现 2.1、初始化 //初始化 void InitQueue(SqQueue &Q…

微信小程序(二十一)css变量-定义页面主题色

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.使用css变量 2.消除按钮白块影响 3.修改图标样式 源码&#xff1a; npmTest.json {"navigationStyle": "custom","usingComponents": {//引入vant组件"van-nav-bar"…

使用py-spy对python程序进行性能诊断学习

py-spy简介 py-spy是一个用Rust编写的轻量级Python分析工具&#xff0c;它能够监视正在运行的Python程序&#xff0c;而不需要修改代码或者重新启动程序。Py-spy可以在不影响程序运行的情况下&#xff0c;采集程序运行时的信息&#xff0c;生成火焰图&#xff08;flame graph&…

API:低代码平台的强大秘诀与无限可能

应用编程接口 (API) 是应用程序以可编程格式访问其关键能力和功能的一种方式&#xff0c;从而其他应用程序可以利用它们。API 本质上支持应用程序之间的无缝数据流&#xff0c;使开发人员能够在应用程序中添加更多功能&#xff0c;而无需依赖大量编码。 举一个简单的例子。 您…

55-工厂模式创建对象,instanceof检测,自定义构造函数

1.对象的概括JavaScript中所有事物都是对象:字符串,数值,数组,函数。对象就是带有属性和方法的特殊数据类型。当函数被保存为一个对象的属性时,它就可以称为这个对象的方法(例如方法模式调用 this指向调用对象) 2.用字面量/自定义对象的方式创建单个对象 <script>/…

华为三层交换机与防火墙对接配置上网示例

三层交换机与防火墙对接上网配置示例 组网图形 图1 三层交换机与防火墙对接上网组网图 三层交换机简介配置注意事项组网需求配置思路操作步骤配置文件 三层交换机简介 三层交换机是具有路由功能的交换机&#xff0c;由于路由属于OSI模型中第三层网络层的功能&#xff0c;所以…

别再做“背锅侠”!软件测试工程师被开发吐槽,如何应对?

作为一名软件测试工程师&#xff0c;我们的角色可以算是“战场上的后勤”&#xff0c;战役的胜败和所有团队人员都息息相关。但是难免碰到战役失败后&#xff0c;很多团队互相推脱的局面&#xff0c;而测试人员就是所有团队中的弱势群体&#xff0c;自然是首当其冲的背锅侠&…

【基础算法练习】单调队列与单调栈模板

文章目录 单调栈模板题代码模板算法思想 单调队列模板题代码模板算法思想 单调栈 模板题 题目链接&#xff1a;ACwing 830. 单调栈 代码模板 #include <iostream> #include <vector> #include <stack>using namespace std;const int N 100010;vector<…

群辉开启WebDav服务+cpolar内网穿透实现移动端ES文件浏览器远程访问本地NAS文件

文章目录 1. 安装启用WebDAV2. 安装cpolar3. 配置公网访问地址4. 公网测试连接5. 固定连接公网地址6. 使用固定地址测试连接 本文主要介绍如何在群辉中开启WebDav服务&#xff0c;并结合cpolar内网穿透工具生成的公网地址&#xff0c;通过移动客户端ES文件浏览器即可实现移动设…

Centos7 单机单网卡安装 OpenStack

本文实际环境 vmware 虚拟机&#xff1a; 网络采用的桥接方式&#xff0c;和我的物理网络在一个网段 CPU开启虚拟化 虚拟机安装系统后&#xff0c;配置上静态IP&#xff0c;能连接外网就行了&#xff0c;最好是把内核升级到5.19以上 1、初始化准备 1&#xff09;关闭防火墙 …