网络资源模板--基于Android Studio 实现的图书馆订座App

发布于:2025-07-07 ⋅ 阅读:(13) ⋅ 点赞:(0)

目录

一、测试环境说明

二、项目简介

三、项目演示

四、部设计详情(部分)

注册页

首页

座位选择

五、项目源码 


一、测试环境说明

二、项目简介

本图书馆预约系统基于Android Studio开发,采用Java语言编写,主要技术包括:

1. 前端使用Android原生组件开发界面,包括Activity、ViewPager、RadioButton等控件

2. 数据存储采用SQLite数据库,通过DAO模式管理用户、座位等数据

3. 网络通信使用OkHttp库调用第三方API获取励志名言数据

4. 使用Gson解析JSON格式的API返回数据

5. 传感器技术实现计步功能,通过加速度传感器检测步伐

6. 采用Material Design设计规范优化UI/UX体验

7. 使用Handler实现延时跳转和轮播图自动切换

三、项目演示

网络资源模板--基于Android studio 图书馆订座App

四、部设计详情(部分)

注册页

注册页面布局与登录页保持风格一致,包含账号、密码和确认密码三个输入字段,以及注册和取消两个操作按钮。

设计上特别强化了表单验证逻辑:实时检查账号是否已存在、密码是否符合复杂度要求、两次输入密码是否一致等,并通过Toast即时反馈验证结果。

用户注册成功后,系统自动填充登录表单并跳转回登录页,优化了用户操作流程。从技术实现看,注册功能同样基于UserDao完成数据持久化,采用标准的Intent机制传递账号密码数据。

页面设计考虑了错误处理场景,如网络异常或数据库操作失败等情况,确保系统的健壮性。清晰的流程指引和即时的操作反馈,使注册过程流畅无阻。

package njust.dzh.libraryreservation.App;

import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;

import njust.dzh.libraryreservation.R;
import njust.dzh.libraryreservation.Bean.User;
import njust.dzh.libraryreservation.DataBase.UserDao;


public class RegisterActivity extends AppCompatActivity {
    private static final int RESULT_OK = 1;

    private Button btnRegister;
    private Button btnCancel;
    private EditText etAccount;
    private EditText etPassword;
    private EditText etConfirmPassword;
    private UserDao userDao;

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

    public void initView() {
        // 去除默认标题栏
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) actionBar.hide();

        // 绑定控件
        etAccount =findViewById(R.id.et_account);
        etPassword = findViewById(R.id.et_password);
        etConfirmPassword = findViewById(R.id.et_confirm_password);
        btnRegister = findViewById(R.id.btn_register);
        btnCancel = findViewById(R.id.btn_cancel);

        // 设置点击事件
        btnRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String acc = etAccount.getText().toString().trim();
                String pass = etPassword.getText().toString().trim();
                String confirm = etConfirmPassword.getText().toString().trim();
                User user = new User(acc, pass);
                userDao = new UserDao(getApplicationContext());
                userDao.open();
                if (userDao.findUser(user)) {
                    Toast.makeText(RegisterActivity.this, "账号已存在", Toast.LENGTH_SHORT).show();
                } else if (TextUtils.isEmpty(pass) || TextUtils.isEmpty(confirm)) {
                    Toast.makeText(RegisterActivity.this, "密码不能为空", Toast.LENGTH_SHORT).show();
                } else if(!pass.equals(confirm)) {
                    Toast.makeText(RegisterActivity.this, "两次输入的密码不同", Toast.LENGTH_SHORT).show();
                } else {
                    userDao.addUser(user);
                    Toast.makeText(RegisterActivity.this, "注册成功!", Toast.LENGTH_SHORT).show();
                    Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
                    //将账号和密码传递过去
                    intent.putExtra("acc", acc);
                    intent.putExtra("pass", pass);
                    setResult(RESULT_OK, intent);
                    finish();
                }
                userDao.close();
            }
        });
        btnCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}

首页

首页采用经典的顶部轮播图加底部功能入口的布局模式。顶部ViewPager实现自动轮播的图片展示区,展示图书馆环境照片和学习提示,每张图片配有对应的指示点,显示当前浏览位置。

中间部分放置楼层选择的单选按钮组,下方排列四个主要功能入口按钮,采用Material Design风格的悬浮按钮作为预约操作入口。

整个页面布局层次分明,重点突出。技术实现上,首页通过Handler定时发送消息实现自动轮播效果,同时监听页面切换事件同步更新指示点状态。

功能按钮采用显眼的视觉设计,确保用户能够快速识别和操作。首页作为系统的中枢,设计上充分考虑了导航的便捷性和视觉的舒适性,为用户提供清晰的操作路径。

<?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=".App.MainActivity"
    android:background="@drawable/bg">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/library_vp"
        android:layout_width="match_parent"
        android:layout_height="250dp" />

    <LinearLayout
        android:id="@+id/point_layout"
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:gravity="center_horizontal"
        android:orientation="horizontal" />
    <Button
        android:id="@+id/reservation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:background="@drawable/bg_button"
        android:layout_margin="20dp"
        android:text="@string/reservation_seats"/>
    <RadioGroup
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginLeft="20dp">
        <RadioButton
            android:id="@+id/first_floor"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="一楼"
            android:checked="true"/>
        <RadioButton
            android:id="@+id/second_floor"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="二楼"/>
        <RadioButton
            android:id="@+id/third_floor"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="三楼"/>
    </RadioGroup>

    <Button
        android:id="@+id/check"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:background="@drawable/bg_button"
        android:layout_margin="20dp"
        android:text="@string/check_seats"/>
    <Button
        android:id="@+id/student"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:background="@drawable/bg_button"
        android:layout_margin="20dp"
        android:text="@string/personal_information"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:orientation="horizontal">
        <Button
            android:id="@+id/step"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:textSize="30sp"
            android:layout_marginRight="5dp"
            android:background="@drawable/bg_button"
            android:text="@string/step"/>
        <Button
            android:id="@+id/exit"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:textSize="30sp"
            android:layout_marginLeft="5dp"
            android:background="@drawable/bg_button"
            android:text="@string/exit"/>
    </LinearLayout>



</LinearLayout>

座位选择

座位选择页面是本系统的核心功能界面,采用直观的矩阵布局模拟实际图书馆座位排列。

每个楼层对应独立的Activity,但保持统一的设计语言:每个座位表示为可选的RadioButton,已预约座位视觉上置灰并禁用,通过颜色区分不同状态。

页面底部设置悬浮的预约确认按钮,点击后弹出二次确认对话框,防止误操作。技术实现上,座位状态数据从本地数据库实时加载,通过遍历View树动态更新界面。

单选按钮分组管理,确保同一时间只能选择一个座位。页面还实现了数据变化后的自动刷新机制,保证用户看到的始终是最新的座位状态。

这种高度仿真的设计大大降低了用户的学习成本,使预约操作直观易懂。

package njust.dzh.libraryreservation.Activity;

import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.util.List;

import njust.dzh.libraryreservation.App.LoginActivity;
import njust.dzh.libraryreservation.Bean.Seat;
import njust.dzh.libraryreservation.DataBase.SeatDao;
import njust.dzh.libraryreservation.R;

public class SecondFloorActivity extends AppCompatActivity {
    private FloatingActionButton fab;
    private SeatDao seatDao;
    private List<Seat> seatList;
    private Seat seat;
    private String account;

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

    // 初始化
    private void initView() {
        initSeats();
        initRadioGroups();
        fab = findViewById(R.id.fab);
        account = getIntent().getStringExtra(LoginActivity.ACCOUNT);

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AlertDialog alertDialog = new AlertDialog.Builder(view.getContext())
                        .setTitle("提示")
                        .setIcon(R.drawable.ic_order)
                        .setMessage("您确定要预订该位置吗?")
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                seatDao.open();
                                if (seatDao.getSeats(account) != null) {
                                    Toast.makeText(SecondFloorActivity.this, "预订失败,您有预订的座位未退订", Toast.LENGTH_SHORT).show();
                                } else {
                                    seatDao.addSecondSeats(seat);
                                    Toast.makeText(SecondFloorActivity.this, "预订成功!", Toast.LENGTH_SHORT).show();
                                }
                                seatDao.close();
                            }
                        })
                        .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                Toast.makeText(SecondFloorActivity.this, "预订已取消", Toast.LENGTH_SHORT).show();
                            }
                        })
                        .show();
            }
        });
    }

    // 初始化所有单选按钮
    private void initSeats() {
        seatDao = new SeatDao(this);
        seatDao.open();
        seatList = seatDao.getSecondSeats();
        seatDao.close();
        // 获取所有单选按钮实例
        RadioButton seat11 = findViewById(R.id.seat11);
        RadioButton seat12 = findViewById(R.id.seat12);
        RadioButton seat13 = findViewById(R.id.seat13);
        RadioButton seat21 = findViewById(R.id.seat21);
        RadioButton seat22 = findViewById(R.id.seat22);
        RadioButton seat31 = findViewById(R.id.seat31);
        RadioButton seat32 = findViewById(R.id.seat32);
        RadioButton seat33 = findViewById(R.id.seat33);
        RadioButton seat41 = findViewById(R.id.seat41);
        RadioButton seat42 = findViewById(R.id.seat42);
        RadioButton seat51 = findViewById(R.id.seat51);
        RadioButton seat52 = findViewById(R.id.seat52);
        RadioButton seat61 = findViewById(R.id.seat61);
        RadioButton seat62 = findViewById(R.id.seat62);
        RadioButton seat63 = findViewById(R.id.seat63);
        RadioButton seat71 = findViewById(R.id.seat71);
        RadioButton seat72 = findViewById(R.id.seat72);
        RadioButton seat81 = findViewById(R.id.seat81);
        RadioButton seat82 = findViewById(R.id.seat82);
        RadioButton seat83 = findViewById(R.id.seat83);

        RadioButton []radioArray = new RadioButton[] {seat11, seat12, seat13, seat21, seat22, seat31,
                seat32, seat33, seat41, seat42, seat51, seat52, seat61, seat62, seat63, seat71, seat72,
                seat81, seat82, seat83};

        // 遍历所有单选按钮
        for (int i = 0; i < radioArray.length; i++) {
            int id = radioArray[i].getId();
            boolean ordered = false;
            // 遍历已选中的单选列表
            for (int j = 0; j < seatList.size(); j++) {
                if (seatList.get(j).getId() == id) {
                    radioArray[i].setBackgroundResource(R.drawable.bg_seats_ordered);
                    radioArray[i].setEnabled(false);
                    ordered = true;
                    break;
                }
            }
            // 退订座位后恢复可选
            if (!ordered && !radioArray[i].isEnabled()) {
                    radioArray[i].setEnabled(true);
                    radioArray[i].setBackgroundResource(R.drawable.bg_seats);
            }
        }
    }

    // 初始化所有单选按钮组
    private void initRadioGroups() {
        RadioGroup radioGroup1 = findViewById(R.id.radio_group1);
        RadioGroup radioGroup2 = findViewById(R.id.radio_group2);
        RadioGroup radioGroup3 = findViewById(R.id.radio_group3);
        RadioGroup radioGroup4 = findViewById(R.id.radio_group4);
        RadioGroup radioGroup5 = findViewById(R.id.radio_group5);
        RadioGroup radioGroup6 = findViewById(R.id.radio_group6);
        RadioGroup radioGroup7 = findViewById(R.id.radio_group7);
        RadioGroup radioGroup8 = findViewById(R.id.radio_group8);
        // 单选按钮组的集合
        RadioGroup [] radioGroups = new RadioGroup[] {radioGroup1, radioGroup2, radioGroup3, radioGroup4,
        radioGroup5, radioGroup6, radioGroup7, radioGroup8};
        // 每一组的监听器
        radioGroup1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                // 清除其他组的选择
                for (int k = 0; k < radioGroups.length; k++) {
                    if (k == 0) continue;
                    if (radioGroups[k].getCheckedRadioButtonId() != -1) {
                        radioGroups[k].clearCheck();
                    }
                }
                // 获取seat对象
                seat = new Seat(i, account);
            }
        });
        radioGroup2.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                // 清除其他行的选择
                for (int k = 0; k < radioGroups.length; k++) {
                    if (k == 1) continue;
                    if (radioGroups[k].getCheckedRadioButtonId() != -1) {
                        radioGroups[k].clearCheck();
                    }
                }
                seat = new Seat(i, account);
            }
        });
        radioGroup3.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                // 清除其他行的选择
                for (int k = 0; k < radioGroups.length; k++) {
                    if (k == 2) continue;
                    if (radioGroups[k].getCheckedRadioButtonId() != -1) {
                        radioGroups[k].clearCheck();
                    }
                }
                seat = new Seat(i, account);
            }
        });
        radioGroup4.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                // 清除其他行的选择
                for (int k = 0; k < radioGroups.length; k++) {
                    if (k == 3) continue;
                    if (radioGroups[k].getCheckedRadioButtonId() != -1) {
                        radioGroups[k].clearCheck();
                    }
                }
                seat = new Seat(i, account);
            }
        });
        radioGroup5.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                // 清除其他行的选择
                for (int k = 0; k < radioGroups.length; k++) {
                    if (k == 4) continue;
                    if (radioGroups[k].getCheckedRadioButtonId() != -1) {
                        radioGroups[k].clearCheck();
                    }
                }
                seat = new Seat(i, account);
            }
        });
        radioGroup6.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                // 清除其他行的选择
                for (int k = 0; k < radioGroups.length; k++) {
                    if (k == 5) continue;
                    if (radioGroups[k].getCheckedRadioButtonId() != -1) {
                        radioGroups[k].clearCheck();
                    }
                }
                seat = new Seat(i, account);
            }
        });
        radioGroup7.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                // 清除其他行的选择
                for (int k = 0; k < radioGroups.length; k++) {
                    if (k == 6) continue;
                    if (radioGroups[k].getCheckedRadioButtonId() != -1) {
                        radioGroups[k].clearCheck();
                    }
                }
                seat = new Seat(i, account);
            }
        });
        radioGroup8.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                // 清除其他行的选择
                for (int k = 0; k < radioGroups.length; k++) {
                    if (k == 7) continue;
                    if (radioGroups[k].getCheckedRadioButtonId() != -1) {
                        radioGroups[k].clearCheck();
                    }
                }
                seat = new Seat(i, account);
            }
        });

    }

}

五、项目源码 

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


网站公告

今日签到

点亮在社区的每一天
去签到