网络资源模板--基于Android Studio 实现的图书商城App

目录

一、测试环境说明

二、项目简介

三、项目演示

四、部设计详情(部分))

登录注册页

首页

五、项目源码


一、测试环境说明

电脑环境

Windows 11

编写语言

JAVA

开发软件

Android Studio (2020)

开发软件只要大于等于测试版本即可(近几年官网直接下载也可以),若是版本低于测试版本请自行测试。项目需要根据你的软件自行适配

二、项目简介

该项目简介来自网络,具体内容需要自行测试

本项目是一个基于Android平台的图书商城应用,采用Java语言开发,使用SQLite作为本地数据库存储方案。

系统实现了完整的电子商务功能流程,包括用户注册登录、图书分类浏览、商品详情查看、购物车管理、订单生成与查询等功能模块。

应用采用MVC架构设计,通过RecyclerView实现高性能列表展示,并利用Navigation组件管理页面导航。在界面设计上,遵循Material Design规范,使用CardView、FloatingActionButton等现代化UI组件提升用户体验。

系统特别设计了分类导航功能,用户可以按计算机、小说、科学、历史等分类浏览图书,并通过购物车批量管理选购商品。

订单模块完整记录了购买历史,支持订单详情查看和删除操作。整个应用充分考虑了移动端特性,实现了流畅的用户交互和稳定的数据存储,为读者提供了便捷的图书购买体验。

该项目由编程乐学团队介入,优化布局完善功能

三、项目演示

网络资源模板--基于Android studio 图书商城App

四、部设计详情(部分)

登录注册页

  1. 页面结构

该页面采用单Activity结构,核心布局由ConstraintLayout构成,内部嵌套MaterialCardView作为登录卡片容器。

卡片内采用垂直LinearLayout组织UI元素,包含标题、用户名输入框、密码输入框、登录按钮和注册切换链接。整体采用居中卡片设计,背景可自定义,输入框使用Material Design的TextInputLayout实现浮动标签效果,按钮采用MaterialButton保持风格统一。

布局层次清晰,间距合理,符合Material Design设计规范。

  1. 使用技术

页面采用AndroidX组件库,使用Material Design组件实现现代化UI,包括MaterialCardView、TextInputLayout和MaterialButton。

数据持久化通过SharedPreferences实现用户名记忆功能。采用MVC模式组织代码,将认证逻辑封装在MyAuth类中。

使用Intent实现页面跳转,并配合清理返回栈。输入验证包括非空检查和错误焦点管理,通过Toast提供用户反馈。

  1. 页面功能详解

该页面提供双模式切换功能,可在登录和注册状态间无缝转换。登录模式下验证用户凭证,注册模式检查用户名唯一性。

自动记忆上次成功登录的用户名提升用户体验。输入验证确保必填字段完整性,错误时自动聚焦对应字段。

认证成功后会清除导航栈直接进入主界面,防止用户回退到登录页。

整体交互流畅,错误处理完善,遵循Material Motion动效原则,视觉层次分明,色彩使用符合Material Design调色板规范。

java 复制代码
package com.example.shop.controllers;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.shop.MyAuth;
import com.example.shop.R;

/**
 * 登录/注册Activity,处理用户认证流程
 * 功能:
 * 1. 登录/注册模式切换
 * 2. 账号密码非空验证
 * 3. 自动填充已保存的用户名
 * 4. 成功登录后跳转主界面
 */
public class LoginActivity extends AppCompatActivity implements View.OnClickListener {

    // UI组件
    private TextView loginTitle;
    private Button authButton;
    private TextView toggleAuthMode;
    private EditText usernameInput;
    private EditText passwordInput;

    // 当前模式标志,true为登录模式,false为注册模式
    private boolean isLoginMode = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 隐藏ActionBar
        if (getSupportActionBar() != null) {
            getSupportActionBar().hide();
        }

        setContentView(R.layout.activity_login);

        // 初始化UI组件
        initViews();

        // 检查是否有保存的用户名,有则自动填充
        checkSavedUsername();
    }

    /**
     * 初始化所有视图组件
     */
    private void initViews() {
        loginTitle = findViewById(R.id.loginTitle);
        authButton = findViewById(R.id.loginButton);
        toggleAuthMode = findViewById(R.id.toggleLoginReg);
        usernameInput = findViewById(R.id.editTextTextEmailAddress);
        passwordInput = findViewById(R.id.editTextTextPassword);

        // 设置点击监听器
        toggleAuthMode.setOnClickListener(this);
        authButton.setOnClickListener(this);
    }

    /**
     * 检查SharedPreferences中是否有保存的用户名
     */
    private void checkSavedUsername() {
        SharedPreferences sp = getSharedPreferences("preferences", MODE_PRIVATE);
        String savedUsername = sp.getString("username", "");
        if (!savedUsername.isEmpty()) {
            usernameInput.setText(savedUsername);
            // 自动聚焦到密码输入框
            passwordInput.requestFocus();
        }
    }

    /**
     * 跳转到主Activity并清除返回栈
     */
    private void navigateToMain() {
        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        finish(); // 结束当前Activity
    }

    /**
     * 切换登录/注册模式
     */
    private void toggleAuthMode() {
        isLoginMode = !isLoginMode;
        loginTitle.setText(isLoginMode ? "登录" : "注册");
        authButton.setText(isLoginMode ? "登录" : "注册");
        toggleAuthMode.setText(isLoginMode ? "立即注册" : "立即登录");
        // 清空密码输入框
        passwordInput.setText("");
    }

    /**
     * 验证输入是否有效
     * @return true表示有效,false表示无效
     */
    private boolean validateInput() {
        String username = usernameInput.getText().toString().trim();
        String password = passwordInput.getText().toString().trim();

        if (username.isEmpty()) {
            showToast("账号不能为空");
            usernameInput.requestFocus();
            return false;
        }

        if (password.isEmpty()) {
            showToast("密码不能为空");
            passwordInput.requestFocus();
            return false;
        }

        return true;
    }

    /**
     * 处理登录逻辑
     */
    private void handleLogin() {
        if (!validateInput()) {
            return;
        }

        String username = usernameInput.getText().toString().trim();
        String password = passwordInput.getText().toString().trim();

        MyAuth auth = new MyAuth(this);
        MyAuth.AuthResult result = auth.authUser(username, password);

        switch (result) {
            case SUCCESS:
                saveUsername(username);
                navigateToMain();
                break;
            case INVALID_USERNAME_OR_PWD:
                showToast("用户名或密码错误");
                passwordInput.setText("");
                passwordInput.requestFocus();
                break;
            case TOKEN_TOO_LONG:
                showToast("用户名太长");
                usernameInput.requestFocus();
                break;
            case UNKNOWN_ERROR:
                showToast("出现未知错误");
                break;
        }
    }

    /**
     * 处理注册逻辑
     */
    private void handleRegistration() {
        if (!validateInput()) {
            return;
        }

        String username = usernameInput.getText().toString().trim();
        String password = passwordInput.getText().toString().trim();

        MyAuth auth = new MyAuth(this);
        MyAuth.AuthResult result = auth.addUser(username, password);

        switch (result) {
            case SUCCESS:
                saveUsername(username);
                navigateToMain();
                break;
            case USER_EXISTED:
                showToast("用户已存在");
                usernameInput.requestFocus();
                break;
            case TOKEN_TOO_LONG:
                showToast("用户名太长");
                usernameInput.requestFocus();
                break;
            case UNKNOWN_ERROR:
                showToast("出现未知错误");
                break;
        }
    }

    /**
     * 保存用户名到SharedPreferences
     * @param username 要保存的用户名
     */
    private void saveUsername(String username) {
        SharedPreferences sp = getSharedPreferences("preferences", MODE_PRIVATE);
        sp.edit().putString("username", username).apply();
    }

    /**
     * 显示Toast消息
     * @param message 要显示的消息
     */
    private void showToast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.toggleLoginReg:
                toggleAuthMode();
                break;
            case R.id.loginButton:
                if (isLoginMode) {
                    handleLogin();
                } else {
                    handleRegistration();
                }
                break;
        }
    }
}

首页

  1. 页面结构

该页面采用垂直LinearLayout布局,顶部为横向滚动的分类导航栏(HorizontalScrollView),底部为RecyclerView展示图书列表。

分类导航栏使用CardView包裹,内部动态生成分类标签卡片。RecyclerView采用GridLayoutManager实现网格布局,支持分类标题跨列显示。

页面结构分为上下两部分,上方分类导航可点击切换,下方图书列表支持点击跳转详情。整体布局简洁高效,分类导航与内容区域联动,提供流畅的浏览体验。

  1. 使用技术

页面基于AndroidX组件库,使用RecyclerView实现高性能列表展示,配合GridLayoutManager实现网格布局。

采用自定义SpanSizeLookup处理分类标题的跨列显示。数据层通过BookService获取图书信息,使用HashMap按分类组织数据。

导航采用Navigation组件实现Fragment间跳转。交互方面实现了RecyclerView滚动监听与分类导航联动,通过动态修改CardView背景色指示当前分类。整体采用观察者模式处理滚动事件,实现双向导航交互。

  1. 页面功能详解

该页面是图书分类浏览界面,顶部导航栏展示所有图书分类,点击可快速定位到对应分类。图书列表按分类分组显示,每个分类标题占据整行,图书以网格形式展示。

滚动列表时导航栏会自动高亮当前分类,反之点击导航栏也会滚动到对应分类。每本图书可点击进入详情页。

页面采用内存优化设计,动态加载分类导航标签,通过位置映射表高效管理分类定位。视觉上通过卡片阴影和颜色对比强化交互反馈,提供直观的分类浏览体验。

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">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        app:cardCornerRadius="0dp"
        app:cardElevation="4dp">

        <HorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0">

            <LinearLayout
                android:id="@+id/linear_pager"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_gravity="start"
                android:orientation="horizontal"
                android:paddingStart="6dp"
                android:paddingEnd="6dp">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="TextView" />

            </LinearLayout>
        </HorizontalScrollView>
    </androidx.cardview.widget.CardView>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/book_list"
        android:name="com.example.shop.BookFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:layoutManager="LinearLayoutManager"
        tools:context=".controllers.BookFragment"
        tools:listitem="@layout/book_fragment_item">

    </androidx.recyclerview.widget.RecyclerView>
</LinearLayout>

五、项目源码

👇👇👇👇👇快捷方式👇👇👇👇👇

相关推荐
梦想改变生活25 分钟前
《Flutter篇第二章》MasonryGridView瀑布流列表
android·flutter
杨航 AI38 分钟前
PHP 5.5 Action Management with Parameters (English Version)
android·开发语言·php
柿蒂2 小时前
一次Android下载优化,CDN消耗占比从50+%到1%
android·android jetpack
真夜2 小时前
关于rn下载gradle依赖速度慢的问题
react native·gradle·android studio
moning2 小时前
Window 的 Type 失效了?IME 为什么在 Toast 下方?
前端·操作系统·android studio
Andrew_Ryan2 小时前
gradle set up
android
_祝你今天愉快4 小时前
在安卓中使用 FFmpegKit 剪切视频并添加文字水印
android·ffmpeg
编程乐学6 小时前
网络资源模板--基于Android Studio 实现的新闻App
android·android studio·移动端开发·新闻·安卓大作业·新闻app
-曾牛6 小时前
PHP 与 MySQL 详解实战入门(1)
android·开发语言·mysql·渗透测试·php·php教程·脚本语言
Monkey-旭7 小时前
深入理解 Kotlin Flow:异步数据流处理的艺术
android·开发语言·kotlin·响应式编程·flow