购物车程序实现教程

购物车程序实现教程

在本教程中,我们将实现一个购物车程序,实现在界面中以列表的形式显示购物车的商品信息。商品信息包含商品名称,价格和数量,并能实现对应的增删改查操作。我们将使用 Android Studio 和 SQLite 数据库来完成这个任务。

程序运行截图




程序设计与说明

我们的购物车程序由以下四个主要类组成:

  1. MainActivity
  2. ProductAdapter
  3. Product
  4. ProductDBHelper

MainActivity

MainActivity 是应用程序的主界面,负责展示购物车内的商品列表,并提供商品的增删改查操作。

主要方法和功能:

  • onCreate(): 初始化界面和设置相应的事件监听器。
  • addPredefinedProducts(): 向数据库添加预定义的商品数据。
  • addProduct(): 添加新商品到购物车。
  • loadProducts(): 从数据库加载购物车内的商品列表并更新 RecyclerView。
  • onProductClick(): 处理商品点击事件,用于弹出编辑商品信息的对话框。
  • showEditProductDialog(): 显示用于编辑商品信息的对话框。
package com.example.shoppingcart;

import android.content.ContentValues;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.NumberPicker;

public class MainActivity extends AppCompatActivity implements ProductAdapter.OnProductClickListener {

    private List<Product> productList = new ArrayList<>();
    private ProductAdapter productAdapter;
    private ProductDBHelper dbHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dbHelper = new ProductDBHelper(this);

        SharedPreferences sharedPreferences = getSharedPreferences("ShoppingCartPreferences", MODE_PRIVATE);
        boolean isFirstRun = sharedPreferences.getBoolean("isFirstRun", true);
        if (isFirstRun) {
            addPredefinedProducts();

            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putBoolean("isFirstRun", false);
            editor.apply();
        }

        RecyclerView shoppingCartList = findViewById(R.id.shopping_cart_list);
        shoppingCartList.setLayoutManager(new LinearLayoutManager(this));
        productAdapter = new ProductAdapter(productList, this);
        shoppingCartList.setAdapter(productAdapter);

        Button addItemButton = findViewById(R.id.add_item_button);
        addItemButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addProduct();
            }
        });

        Button viewCartButton = findViewById(R.id.view_cart_button);
        viewCartButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showCartDialog();
            }
        });

        loadProducts();
    }


    private void addPredefinedProducts() {
        SQLiteDatabase db = dbHelper.getWritableDatabase();

        // 商品列表
        List<Product> predefinedProducts = new ArrayList<>();
        predefinedProducts.add(new Product("iPhone 13", 1099.00, 1));
        predefinedProducts.add(new Product("Samsung Galaxy S22", 999.00, 1));
        predefinedProducts.add(new Product("Google Pixel 6", 899.00, 1));

        for (Product product : predefinedProducts) {
            ContentValues values = new ContentValues();
            values.put(ProductDBHelper.COLUMN_NAME, product.getName());
            values.put(ProductDBHelper.COLUMN_PRICE, product.getPrice());
            values.put(ProductDBHelper.COLUMN_QUANTITY, product.getQuantity());

            long newRowId = db.insert(ProductDBHelper.TABLE_NAME, null, values);
            if (newRowId == -1) {
                Toast.makeText(this, "添加商品失败", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void addProduct() {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(ProductDBHelper.COLUMN_NAME, "商品" + (productList.size() + 1));
        values.put(ProductDBHelper.COLUMN_PRICE, 9.99);
        values.put(ProductDBHelper.COLUMN_QUANTITY, 1);

        long newRowId = db.insert(ProductDBHelper.TABLE_NAME, null, values);
        if (newRowId != -1) {
            loadProducts();
            Toast.makeText(this, "商品已添加", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "添加商品失败", Toast.LENGTH_SHORT).show();
        }
    }

    private void loadProducts() {
        productList.clear();
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        String[] projection = {
                ProductDBHelper.COLUMN_ID,
                ProductDBHelper.COLUMN_NAME,
                ProductDBHelper.COLUMN_PRICE,
                ProductDBHelper.COLUMN_QUANTITY
        };

        Cursor cursor = db.query(
                ProductDBHelper.TABLE_NAME,
                projection,
                null,
                null,
                null,
                null,
                null
        );

        while (cursor.moveToNext()) {
            String name = cursor.getString(cursor.getColumnIndex(ProductDBHelper.COLUMN_NAME));
            double price = cursor.getDouble(cursor.getColumnIndex(ProductDBHelper.COLUMN_PRICE));
            int quantity = cursor.getInt(cursor.getColumnIndex(ProductDBHelper.COLUMN_QUANTITY));
            int id = cursor.getInt(cursor.getColumnIndex(ProductDBHelper.COLUMN_ID));
            productList.add(new Product(id, name, price, quantity));
        }
        cursor.close();
        productAdapter.notifyDataSetChanged();
    }


    @Override
    public void onProductClick(Product product) {
        showEditProductDialog(product);
    }

    private void showEditProductDialog(final Product product) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("编辑商品");

        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);

        final EditText nameEditText = new EditText(this);
        nameEditText.setText(product.getName());
        layout.addView(nameEditText);

        final EditText priceEditText = new EditText(this);
        priceEditText.setText(String.valueOf(product.getPrice()));
        layout.addView(priceEditText);

        final NumberPicker quantityPicker = new NumberPicker(this);
        quantityPicker.setMinValue(1);
        quantityPicker.setMaxValue(100);
        quantityPicker.setValue(product.getQuantity());
        layout.addView(quantityPicker);

        builder.setView(layout);

        builder.setPositiveButton("保存", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String newName = nameEditText.getText().toString();
                double newPrice = Double.parseDouble(priceEditText.getText().toString());
                int newQuantity = quantityPicker.getValue();

                Product updatedProduct = new Product(product.getId(), newName, newPrice, newQuantity);
                dbHelper.updateProduct(updatedProduct);
                loadProducts();
            }
        });

        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });

        builder.setNeutralButton("删除", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dbHelper.deleteProduct(product.getId());
                loadProducts();
            }
        });

        builder.show();
    }
    private void showCartDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("购物车");

        StringBuilder cartItems = new StringBuilder();
        double total = 0;
        for (Product product : productList) {
            if (product.isSelected()) {
                cartItems.append(product.getName())
                        .append(" x ")
                        .append(product.getQuantity())
                        .append(" = ")
                        .append(String.format(Locale.getDefault(), "%.2f", product.getPrice() * product.getQuantity()))
                        .append("\n");
                total += product.getPrice() * product.getQuantity();
            }
        }

        cartItems.append("\n总计:").append(String.format(Locale.getDefault(), "%.2f", total));
        builder.setMessage(cartItems.toString());
        builder.setPositiveButton("确定", (dialog, which) -> dialog.dismiss());

        builder.setNegativeButton("清空购物车", (dialog, which) -> {
            for (Product product : productList) {
                product.setSelected(false);
            }
            productAdapter.notifyDataSetChanged();
            dialog.dismiss();
        });

        builder.show();
    }

}

ProductAdapter

ProductAdapter 是一个自定义的 RecyclerView.Adapter,负责将商品数据与 RecyclerView 中的视图进行绑定。

主要方法和功能:

  • onCreateViewHolder(): 创建 ViewHolder,用于承载商品视图。
  • onBindViewHolder(): 将商品数据与视图进行绑定。
  • getItemCount(): 返回购物车内商品的数量。
  • OnProductClickListener: 定义一个接口,用于处理商品点击事件。
package com.example.shoppingcart;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;
import java.util.Locale;

public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ViewHolder> {

    private List<Product> productList;
    private OnProductClickListener onProductClickListener;

    public ProductAdapter(List<Product> productList, OnProductClickListener onProductClickListener) {
        this.productList = productList;
        this.onProductClickListener = onProductClickListener;
    }
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_item, parent, false);
        return new ViewHolder(view, onProductClickListener);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Product product = productList.get(position);
        holder.nameTextView.setText(product.getName());
        holder.priceTextView.setText(String.format(Locale.getDefault(), "%.2f", product.getPrice()));
        holder.quantityTextView.setText(String.valueOf(product.getQuantity()));
        holder.selectedCheckbox.setChecked(product.isSelected());

        // Handle checkbox click
        holder.selectedCheckbox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                product.setSelected(!product.isSelected());
            }
        });
    }

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

    public interface OnProductClickListener {
        void onProductClick(Product product);
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView nameTextView;
        public TextView priceTextView;
        public TextView quantityTextView;
        CheckBox selectedCheckbox;

        public ViewHolder(View itemView, OnProductClickListener onProductClickListener) {
            super(itemView);
            nameTextView = itemView.findViewById(R.id.product_name);
            priceTextView = itemView.findViewById(R.id.product_price);
            quantityTextView = itemView.findViewById(R.id.product_quantity);
            itemView.setOnClickListener(this);
            selectedCheckbox = itemView.findViewById(R.id.product_selected_checkbox);
        }

        @Override
        public void onClick(View v) {
            if (onProductClickListener != null) {
                onProductClickListener.onProductClick(productList.get(getAdapterPosition()));
            }
        }
    }
}


Product

Product 类表示购物车内的商品,包含商品的基本信息,如 ID、名称、价格和数量。

主要方法和功能:

  • 构造函数: 初始化商品实例。
  • Getter 和 Setter 方法: 访问和修改商品属性。
package com.example.shoppingcart;

public class Product {
    private int id;
    private String name;
    private double price;
    private int quantity;
    private boolean selected;

    public Product(int id, String name, double price, int quantity) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.quantity = quantity;
    }

    public Product(String name, double price, int quantity) {
        this.name = name;
        this.price = price;
        this.quantity = quantity;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public double getPrice() {
        return price;
    }

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

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }
}

ProductDBHelper

ProductDBHelper 是一个自定义的 SQLiteOpenHelper 类,负责管理商品数据的数据库操作,如创建表、更新表、查询数据、更新数据和删除数据。

主要方法和功能:

  • onCreate(): 创建商品表。
  • onUpgrade(): 删除旧的商品表,并重新创建。
  • updateProduct(): 更新商品信息。
  • deleteProduct(): 删除商品。
package com.example.shoppingcart;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class ProductDBHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "shopping_cart.db";
    private static final int DATABASE_VERSION = 1;

    public static final String TABLE_NAME = "products";
    public static final String COLUMN_ID = "id";
    public static final String COLUMN_NAME = "name";
    public static final String COLUMN_PRICE = "price";
    public static final String COLUMN_QUANTITY = "quantity";

    private static final String SQL_CREATE_ENTRIES =
            "CREATE TABLE " + TABLE_NAME + " (" +
                    COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                    COLUMN_NAME + " TEXT," +
                    COLUMN_PRICE + " REAL," +
                    COLUMN_QUANTITY + " INTEGER)";

    private static final String SQL_DELETE_ENTRIES =
            "DROP TABLE IF EXISTS " + TABLE_NAME;

    public ProductDBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_ENTRIES);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(SQL_DELETE_ENTRIES);
        onCreate(db);
    }

    public int updateProduct(Product product) {
        SQLiteDatabase db = getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(COLUMN_NAME, product.getName());
        values.put(COLUMN_PRICE, product.getPrice());
        values.put(COLUMN_QUANTITY, product.getQuantity());

        String selection = COLUMN_ID + " = ?";
        String[] selectionArgs = {String.valueOf(product.getId())};

        return db.update(TABLE_NAME, values, selection, selectionArgs);
    }

    public int deleteProduct(int productId) {
        SQLiteDatabase db = getWritableDatabase();

        String selection = COLUMN_ID + " = ?";
        String[] selectionArgs = {String.valueOf(productId)};

        return db.delete(TABLE_NAME, selection, selectionArgs);
    }
}

总结

通过这四个类的协同工作,实现了购物车程序的核心功能。具体来说,MainActivity 负责展示商品列表和操作界面,ProductAdapter 负责将商品数据绑定到视图上,Product 类表示购物车中的商品,而 ProductDBHelper 负责对商品数据进行增删改查操作。希望本教程对你有所帮助!

源码

源码地址
转载请标注,希望点个订阅!

  • 1
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值