网络资源模板--Android Studio 实现宿舍管理系统App

目录

一、项目演示

二、项目测试环境

三、项目详情

四、完整的项目源码


一、项目演示

网络资源模板--基于Android studio 实现的宿舍管理系统

二、项目测试环境

三、项目详情

所有项目页面展示:

登录页

  1. 界面组件

    • 包含账户输入框(etAccount)和密码输入框(etPassword)。
    • 有一个登录按钮(btnLogin)和一个注册文本视图(tvRegister)。
  2. 注册跳转

    • 点击注册文本视图会跳转到注册界面。
  3. 登录逻辑

    • 用户输入账户和密码后,首先检查输入是否为空。
    • 如果账户和密码都不为空,则通过SQLite数据库查询用户信息。
    • 如果用户存在,进一步验证密码是否正确。
    • 登录成功后,用户ID和用户类型被保存到SharedPreferences中,并跳转到主界面;如果登录失败,则显示相应的错误提示(如"账号不存在"或"密码错误")。
  4. 数据库操作

    • 使用MySqliteOpenHelper类管理SQLite数据库,查询用户数据。
  5. 用户反馈

    • 通过Toast提供即时反馈,提示用户输入错误或登录状态。
java 复制代码
package com.example.studentdormitory.ui.activity;

import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.studentdormitory.R;
import com.example.studentdormitory.bean.User;
import com.example.studentdormitory.util.MySqliteOpenHelper;
import com.example.studentdormitory.util.SPUtils;

public class LoginActivity extends AppCompatActivity {
    private Button btnLogin; // 登录按钮
    private EditText etAccount; // 账户输入框
    private EditText etPassword; // 密码输入框
    private MySqliteOpenHelper helper; // SQLite数据库帮助类
    private TextView tvRegister; // 注册文本视图

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login); // 设置布局

        helper = new MySqliteOpenHelper(this); // 初始化数据库帮助类
        etAccount = findViewById(R.id.et_account); // 获取账户输入框
        etPassword = findViewById(R.id.et_password); // 获取密码输入框
        tvRegister = findViewById(R.id.tv_register); // 获取注册文本视图
        btnLogin = findViewById(R.id.btn_login); // 获取登录按钮

        // 注册点击事件,跳转到注册界面
        tvRegister.setOnClickListener(v -> startActivity(new Intent(LoginActivity.this, RegisterActivity.class)));

        // 登录按钮点击事件
        btnLogin.setOnClickListener(v -> {
            String account = etAccount.getText().toString(); // 获取账户输入
            String password = etPassword.getText().toString(); // 获取密码输入

            // 检查账户是否为空
            // 检查用户名是否为空
            if (account.isEmpty()) {
                Toast.makeText(LoginActivity.this, "用户名不能为空", Toast.LENGTH_SHORT).show();
            }
            // 检查密码是否为空
            else if (password.isEmpty()) {
                Toast.makeText(LoginActivity.this, "密码不能为空", Toast.LENGTH_SHORT).show();
            }

            // 如果账户和密码都不为空
            else {
                User mUser = null; // 声明用户对象
                SQLiteDatabase db = helper.getWritableDatabase(); // 获取可写数据库
                // 查询账户是否存在
                Cursor cursor = db.rawQuery("select * from user where account = ?", new String[]{account});
                if (cursor != null && cursor.getCount() > 0) {
                    while (cursor.moveToNext()) {
                        // 从数据库中获取用户信息
                        mUser = new User(cursor.getInt(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4), cursor.getString(5), cursor.getString(6), cursor.getString(7), cursor.getInt(8));
                    }
                }
                cursor.close(); // 关闭游标
                db.close(); // 关闭数据库

                // 检查用户是否存在
                if (mUser == null) {
                    Toast.makeText(LoginActivity.this, "账号不存在", Toast.LENGTH_SHORT).show();
                }
                // 检查密码是否正确
                else if (!password.equals(mUser.getPassword())) {
                    Toast.makeText(LoginActivity.this, "密码错误", Toast.LENGTH_SHORT).show();
                }
                // 登录成功
                else {
                    SPUtils.put(LoginActivity.this, SPUtils.USER_ID, mUser.getId()); // 保存用户ID
                    SPUtils.put(LoginActivity.this, SPUtils.USER_TYPE, mUser.getUserType()); // 保存用户类型
                    startActivity(new Intent(LoginActivity.this, MainActivity.class)); // 跳转到主界面
                    finish(); // 结束当前活动
                }
            }
        });
    }
}

注册页

  1. 用户信息输入:

    • 提供了多个输入框供用户填写,包括账号、昵称、密码、确认密码、手机号和寝室号。
  2. 头像选择:

    • 允许用户点击头像ImageView选择图片,并使用Glide库加载选择的头像。
  3. 性别选择:

    • 用户可以通过RadioGroup选择性别。
  4. 数据验证:

    • 在用户点击注册按钮时,系统会进行多项验证,包括:
      • 头像是否已上传。
      • 账号、昵称、手机号、寝室号、密码等输入框不能为空。
      • 手机号格式是否正确(长度为11)。
      • 确认密码是否与密码一致。
  5. 用户注册逻辑:

    • 查询数据库以检查账号是否已存在。
    • 若账号不存在,则插入新用户信息到数据库。
    • 注册成功后显示提示信息,并结束当前活动。
    • 若账号已存在,则显示相应提示信息。
  6. 跳转到登录界面:

    • 提供一个文本链接,允许用户跳转回登录界面。
java 复制代码
package com.example.studentdormitory.ui.activity;

import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.example.studentdormitory.R;
import com.example.studentdormitory.bean.User;
import com.example.studentdormitory.enums.UserTypeEnum;
import com.example.studentdormitory.util.GlideEngine;
import com.example.studentdormitory.util.MySqliteOpenHelper;
import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.listener.OnResultCallbackListener;

import java.util.List;

public class RegisterActivity extends AppCompatActivity {
    private Button btnRegister; // 注册按钮
    private EditText etAccount, etNickName, etPassword, etPasswordSure, etPhone, etRoom; // 输入框
    private RequestOptions headerRO = new RequestOptions().circleCrop(); // 头像请求选项
    private MySqliteOpenHelper helper; // 数据库助手
    private String imagePath = ""; // 头像路径
    private ImageView ivPhoto; // 头像ImageView
    private RadioGroup rgSex; // 性别选择组
    private TextView tvLogin; // 登录文本

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register); // 设置布局
        helper = new MySqliteOpenHelper(this); // 初始化数据库助手

        // 初始化UI组件
        etAccount = findViewById(R.id.et_account);
        etNickName = findViewById(R.id.et_nickName);
        etPhone = findViewById(R.id.et_phone);
        etRoom = findViewById(R.id.et_room);
        etPassword = findViewById(R.id.et_password);
        etPasswordSure = findViewById(R.id.et_password_sure);
        ivPhoto = findViewById(R.id.iv_photo);
        rgSex = findViewById(R.id.rg_sex);
        tvLogin = findViewById(R.id.tv_login);
        btnRegister = findViewById(R.id.btn_register);

        // 设置头像点击事件,选择图片
        ivPhoto.setOnClickListener(v -> selectClick());

        // 设置登录文本点击事件,跳转到登录界面
        tvLogin.setOnClickListener(v -> {
            startActivity(new Intent(RegisterActivity.this, LoginActivity.class));
            finish(); // 关闭当前活动
        });

        // 设置注册按钮点击事件
        btnRegister.setOnClickListener(v -> {
            String account = etAccount.getText().toString();
            String nickName = etNickName.getText().toString();
            String phone = etPhone.getText().toString();
            String room = etRoom.getText().toString();
            String password = etPassword.getText().toString();
            String passwordSure = etPasswordSure.getText().toString();

            // 检查输入的有效性
            if (TextUtils.isEmpty(imagePath)) {
                Toast.makeText(RegisterActivity.this, "请上传头像", Toast.LENGTH_SHORT).show();
            } else if (TextUtils.isEmpty(account)) {
                Toast.makeText(RegisterActivity.this, "用户名不能为空", Toast.LENGTH_SHORT).show();
            } else if (TextUtils.isEmpty(nickName)) {
                Toast.makeText(RegisterActivity.this, "昵称不能为空", Toast.LENGTH_SHORT).show();
            } else if (TextUtils.isEmpty(phone)) {
                Toast.makeText(RegisterActivity.this, "手机号不能为空", Toast.LENGTH_SHORT).show();
            } else if (phone.length() != 11) {
                Toast.makeText(RegisterActivity.this, "手机号格式错误", Toast.LENGTH_SHORT).show();
            } else if (TextUtils.isEmpty(room)) {
                Toast.makeText(RegisterActivity.this, "寝室不能为空", Toast.LENGTH_SHORT).show();
            } else if (TextUtils.isEmpty(password)) {
                Toast.makeText(RegisterActivity.this, "密码为空", Toast.LENGTH_SHORT).show();
            } else if (!password.equals(passwordSure)) {
                Toast.makeText(RegisterActivity.this, "密码不一致", Toast.LENGTH_SHORT).show();
            } else {
                // 获取性别
                String sex = rgSex.getCheckedRadioButtonId() == R.id.rb_man ? "男" : "女";
                User mUser = null; // 用户对象
                SQLiteDatabase db = helper.getWritableDatabase(); // 获取可写数据库
                Cursor cursor = db.rawQuery("select * from user where account = ?", new String[]{account}); // 查询是否已存在用户

                if (cursor != null && cursor.getCount() > 0) {
                    while (cursor.moveToNext()) {
                        mUser = new User(cursor.getInt(0), cursor.getString(1), cursor.getString(2),
                                cursor.getString(3), cursor.getString(4), cursor.getString(5),
                                cursor.getString(6), cursor.getString(7), cursor.getInt(8));
                    }
                }

                // 如果用户不存在,插入新用户
                if (mUser == null) {
                    db.execSQL("insert into user(account, password,name,sex, phone,room,photo,userType) values(?,?,?,?,?,?,?,?)",
                            new Object[]{account, password, nickName, sex, phone, room, imagePath, UserTypeEnum.User.getCode()});
                    Toast.makeText(RegisterActivity.this, "注册成功", Toast.LENGTH_SHORT).show();
                    finish(); // 关闭当前活动
                } else {
                    Toast.makeText(RegisterActivity.this, "该账号已存在", Toast.LENGTH_SHORT).show();
                }
                db.close(); // 关闭数据库
            }
        });
    }

    // 选择头像的方法
    private void selectClick() {
        PictureSelector.create(this)
                .openGallery(PictureMimeType.ofImage()) // 打开图片选择器
                .imageEngine(GlideEngine.createGlideEngine()) // 设置图片加载引擎
                .maxSelectNum(1) // 限制最多选择一张图片
                .forResult(new OnResultCallbackListener<LocalMedia>() {
                    @Override
                    public void onResult(List<LocalMedia> result) {
                        String path = result.get(0).getPath(); // 获取选择的图片路径
                        imagePath = path; // 更新头像路径
                        Glide.with(RegisterActivity.this).load(imagePath).into(ivPhoto); // 加载图片
                    }

                    @Override
                    public void onCancel() {
                    } // 取消选择时的回调
                });
    }

    // 返回按钮点击事件
    public void back(View view) {
        finish(); // 关闭当前活动
    }
}

首页

  1. Fragment管理:

    • 该活动使用数组 fragments 来存储不同的Fragment,便于在用户界面中进行切换。
    • 提供了三个主要Fragment:学生首页(StudentHomeFragment)、管理员首页(AdminHomeFragment)、用户管理(UserManageFragment)和用户信息(UserFragment)。
  2. 用户类型判断:

    • 使用 SPUtils 获取用户类型,以决定显示的Fragment。不同用户类型(学生或管理员)会导致不同的Fragment切换逻辑。
  3. 界面初始化:

    • onCreate 方法中,初始化视图组件,包括标题、内容布局和三个RadioButton。
    • 根据用户类型控制"管理"按钮的可见性。
  4. 按钮点击监听:

    • 为每个RadioButton设置点击事件,点击不同按钮会更新标题并切换相应的Fragment。
  5. Fragment切换逻辑:

    • switchFragment(int fragmentIndex) 方法用于切换当前显示的Fragment。根据用户类型和选中的Fragment创建相应的Fragment实例,并管理Fragment的显示和隐藏。
  6. 返回键处理:

    • 通过重写 onKeyDown 方法来处理返回键,提供了双击退出的功能。
java 复制代码
package com.example.studentdormitory.ui.activity;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.example.studentdormitory.R;
import com.example.studentdormitory.enums.UserTypeEnum;
import com.example.studentdormitory.ui.fragment.AdminHomeFragment;
import com.example.studentdormitory.ui.fragment.StudentHomeFragment;
import com.example.studentdormitory.ui.fragment.UserFragment;
import com.example.studentdormitory.ui.fragment.UserManageFragment;
import com.example.studentdormitory.util.SPUtils;

public class MainActivity extends AppCompatActivity {
    private Fragment[] fragments = {null, null, null}; // 用于存储不同的Fragment
    private LinearLayout llContent; // 主内容布局
    private Activity myActivity; // 当前Activity引用
    private RadioButton rbHome; // 首页按钮
    private RadioButton rbManage; // 管理按钮
    private RadioButton rbUser; // 用户按钮
    private long time = 0; // 用于记录时间
    private TextView tvTitle; // 标题文本
    private Integer userType; // 用户类型

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

        // 初始化视图组件
        tvTitle = findViewById(R.id.title);
        llContent = findViewById(R.id.ll_main_content);
        rbHome = findViewById(R.id.rb_main_home);
        rbManage = findViewById(R.id.rb_main_manage);
        rbUser = findViewById(R.id.rb_main_user);

        initView(); // 初始化视图
        setViewListener(); // 设置视图监听器
    }

    // 设置按钮点击监听器
    private void setViewListener() {
        rbHome.setOnClickListener(v -> {
            tvTitle.setText("首页");
            switchFragment(0); // 切换到首页Fragment
        });
        rbManage.setOnClickListener(v -> {
            tvTitle.setText("学生管理");
            switchFragment(1); // 切换到学生管理Fragment
        });
        rbUser.setOnClickListener(v -> {
            tvTitle.setText("我的");
            // 根据用户类型切换到相应的Fragment
            switchFragment(userType.intValue() == UserTypeEnum.User.getCode() ? 1 : 2);
        });
    }

    // 初始化视图组件
    private void initView() {
        userType = (Integer) SPUtils.get(myActivity, SPUtils.USER_TYPE, 0); // 获取用户类型

        // 设置首页按钮图标
        setRadioButtonIcon(rbHome, R.drawable.selector_main_rb_home);
        // 设置管理按钮图标
        setRadioButtonIcon(rbManage, R.drawable.selector_main_rb_manage);
        // 设置用户按钮图标
        setRadioButtonIcon(rbUser, R.drawable.selector_main_rb_user);

        switchFragment(0); // 默认显示首页
        // 根据用户类型决定管理按钮的可见性
        rbManage.setVisibility(userType.intValue() == UserTypeEnum.User.getCode() ? View.GONE : View.VISIBLE);
        rbHome.setChecked(true); // 默认选中首页按钮
    }

    // 设置RadioButton图标的封装方法
    private void setRadioButtonIcon(RadioButton radioButton, int drawableId) {
        Drawable icon = getResources().getDrawable(drawableId);
        icon.setBounds(0, 0, 68, 68);
        radioButton.setCompoundDrawables(null, icon, null, null);
        radioButton.setCompoundDrawablePadding(5); // 设置图标与文本的间距
    }

    // 切换Fragment
    private void switchFragment(int fragmentIndex) {
        FragmentTransaction transaction = getFragmentManager().beginTransaction(); // 开启事务

        if (fragments[fragmentIndex] == null) {
            // 根据用户类型和选中的Fragment创建相应的Fragment实例
            if (userType.intValue() == UserTypeEnum.User.getCode()) {
                if (fragmentIndex == 0) {
                    fragments[fragmentIndex] = new StudentHomeFragment(); // 学生首页
                } else if (fragmentIndex == 1) {
                    fragments[fragmentIndex] = new UserFragment(); // 用户信息
                }
            } else {
                if (fragmentIndex == 0) {
                    fragments[fragmentIndex] = new AdminHomeFragment(); // 管理员首页
                } else if (fragmentIndex == 1) {
                    fragments[fragmentIndex] = new UserManageFragment(); // 用户管理
                } else if (fragmentIndex == 2) {
                    fragments[fragmentIndex] = new UserFragment(); // 用户信息
                }
            }
            transaction.add(R.id.ll_main_content, fragments[fragmentIndex]); // 添加Fragment
        }

        // 隐藏其他Fragment
        for (int i = 0; i < fragments.length; i++) {
            if (fragmentIndex != i && fragments[i] != null) {
                transaction.hide(fragments[i]); // 隐藏不需要的Fragment
            }
        }

        transaction.show(fragments[fragmentIndex]); // 显示选中的Fragment
        transaction.commit(); // 提交事务
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            exit(); // 处理返回键
            return true;
        }
        return false;
    }

    // 处理应用退出
    public void exit() {
        if (System.currentTimeMillis() - time > 2000) {
            time = System.currentTimeMillis(); // 更新退出时间
            Toast.makeText(myActivity, "再点击一次退出应用程序", Toast.LENGTH_SHORT).show(); // 提示信息
        } else {
            finish(); // 关闭应用
        }
    }
}

四、完整的项目源码

👇👇👇👇👇快捷获取方式👇👇👇👇👇

相关推荐
hanruanjian2 小时前
CDR2024官方学习版安装包+升级补丁包+注册机
android·windows·学习·microsoft·macos·idm
量子位2 小时前
机器人世界模型,TeleAI 用少量数据完成训练 | NeurIPS 2024
android·人工智能
wy3136228213 小时前
android——Groovy gralde 脚本迁移到DSL
android·前端·javascript
命运之手3 小时前
【Android】Custom Action Mode Menu
android·edittext·actionmode·contextmenu
追梦的鱼儿3 小时前
Git之代已修改文件的目录高亮设置
android·git·intellij-idea·目录·高亮
Mac Zhu4 小时前
sealed class-kotlin中的封闭类
android·kotlin
zhaoyufei1334 小时前
Android App系统签名
android
aqi006 小时前
FFmpeg开发笔记(五十七)使用Media3的Transformer加工视频文件
android·ffmpeg·音视频·直播·流媒体
yijiaodingqiankun8 小时前
新版(考拉版)Android Studio2024.1.2版 如何用无线(WiFi)连接Android手机
android·智能手机·android studio