目录
一、测试环境说明
二、项目简介
《宠物领养》是一款基于Android平台开发的宠物领养管理应用,旨在为有爱心的人们与需要家庭的可爱宠物之间搭建一座爱心桥梁。
该项目采用Material Design设计风格,为用户提供简洁美观的交互体验。
首页浏览:用户可以浏览所有待领养的宠物信息,支持按类别(全部、猫咪、狗狗)进行筛选,每个宠物都有详细的档案信息,包括姓名、性别、年龄、体重、地址、品种、毛色、性格特点、兴趣爱好以及健康状况等。
发现页面:提供更多宠物信息的探索功能,帮助用户发现更多可爱的宠物朋友。
个人中心:用户可以管理自己的账户信息,查看个人的领养记录和收藏的宠物列表,追踪自己的爱心足迹。
收藏与领养:用户可以收藏感兴趣的宠物,并可以提交领养申请。系统会记录用户的收藏时间和领养状态。
用户管理:包含完整的用户注册、登录功能,以及管理员后台管理系统,确保平台的规范运营。
该项目采用经典的Android原生开发架构:
前端界面:使用Fragment + BottomNavigationView实现底部导航,提供流畅的页面切换体验
数据管理:基于SQLite数据库进行本地数据存储,包含用户、宠物、领养记录、收藏记录等完整的数据模型
代码结构:遵循MVC架构模式,代码组织清晰,包含实体类(Entity)、数据访问层(DAO)、界面层(UI)等模块
这是一个充满爱心的公益性项目,通过技术手段让更多的宠物找到温暖的家,让爱心人士能够便捷地参与到宠物救助领养活动中来。
三、项目演示
网络资源模板--基于Android studio 宠物领养App
四、部设计详情(部分)
登录页
package com.example.petadopt.ui.activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.example.petadopt.R;
import com.example.petadopt.common.Result;
import com.example.petadopt.dao.PetDao;
import com.example.petadopt.dao.UserDao;
import com.example.petadopt.entity.Pet;
import com.example.petadopt.entity.User;
import com.example.petadopt.utils.CurrentUserUtils;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class LoginActivity extends AppCompatActivity {
private EditText etUsername;
private EditText etPassword;
private Button btnLogin;
private TextView tvRegister;
private ImageView ivTogglePassword;
private CheckBox cbAdminLogin;
private boolean isPasswordVisible = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
importPetData();
initView();
initListener();
XXPermissions.with(this)
.permission(Permission.WRITE_EXTERNAL_STORAGE)
.permission(Permission.READ_MEDIA_IMAGES)
.request(new OnPermissionCallback() {
@Override
public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
}
});
}
/**
* 从assets导入宠物数据
*/
private void importPetData() {
if (PetDao.getPetCount() > 0) {
// 如果数据库中已有数据,则不进行导入
return;
}
try {
// 打开JSON文件
InputStream inputStream = getAssets().open("pet.json");
// 从JSON加载宠物数据
Result<List<Pet>> result = PetDao.loadPetsFromAssets(inputStream);
if (result.isSuccess() && result.getData() != null) {
List<Pet> petList = result.getData();
// 将宠物数据导入到数据库
Result<Void> importResult = PetDao.importPetsFromJson(petList);
if (!importResult.isSuccess()) {
Toast.makeText(this, importResult.getMessage(), Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, result.getMessage(), Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "导入数据失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private void initView() {
etUsername = findViewById(R.id.et_username);
etPassword = findViewById(R.id.et_password);
btnLogin = findViewById(R.id.btn_login);
tvRegister = findViewById(R.id.tv_register);
ivTogglePassword = findViewById(R.id.iv_toggle_password);
cbAdminLogin = findViewById(R.id.cb_admin_login);
}
private void initListener() {
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = etUsername.getText().toString().trim();
String password = etPassword.getText().toString().trim();
if (username.isEmpty()) {
Toast.makeText(LoginActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show();
return;
}
if (password.isEmpty()) {
Toast.makeText(LoginActivity.this, "请输入密码", Toast.LENGTH_SHORT).show();
return;
}
// 判断是否是管理员登录
if (cbAdminLogin.isChecked()) {
// 管理员登录验证
if ("admin".equals(username) && "admin".equals(password)) {
Toast.makeText(LoginActivity.this, "管理员登录成功", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(LoginActivity.this, AdminActivity.class);
startActivity(intent);
finish();
} else {
Toast.makeText(LoginActivity.this, "管理员用户名或密码错误", Toast.LENGTH_SHORT).show();
}
} else {
// 普通用户登录验证
Result<User> loginResult = UserDao.login(username, password);
if (loginResult.isSuccess()) {
// 登录成功,保存当前用户ID
User user = loginResult.getData();
CurrentUserUtils.setCurrentUser(user.getId());
Toast.makeText(LoginActivity.this, loginResult.getMessage(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
} else {
// 登录失败
Toast.makeText(LoginActivity.this, loginResult.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
});
tvRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
startActivity(intent);
}
});
ivTogglePassword.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
togglePasswordVisibility();
}
});
cbAdminLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (cbAdminLogin.isChecked()) {
// 提示管理员登录信息
Toast.makeText(LoginActivity.this, "请使用管理员账户登录", Toast.LENGTH_SHORT).show();
etUsername.setHint("管理员用户名");
etPassword.setHint("管理员密码");
} else {
// 恢复普通提示
etUsername.setHint("请输入用户名");
etPassword.setHint("请输入密码");
}
}
});
}
private void togglePasswordVisibility() {
if (isPasswordVisible) {
// 隐藏密码
etPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
ivTogglePassword.setImageResource(R.drawable.ic_password_hide); // 设置为不可见图标
} else {
// 显示密码
etPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
ivTogglePassword.setImageResource(R.drawable.ic_password_show); // 设置为可见图标
}
isPasswordVisible = !isPasswordVisible;
// 将光标移到文本末尾
etPassword.setSelection(etPassword.getText().length());
}
}
1. 页面的结构
该登录页面采用经典的垂直线性布局,整体结构清晰明了。顶部是应用Logo和欢迎文案,中间是登录表单区域,包含用户名、密码输入框和登录按钮,底部是注册引导链接。
页面使用NestedScrollView作为根布局确保内容可滚动,表单元素采用Material Design风格设计,包括带图标的密码可见性切换功能和管理员登录选项。
布局层次分明,重要操作按钮突出显示,整体符合现代Android应用的设计规范。
2. 使用到的技术
该页面运用了多种Android开发核心技术:使用XXPermissions库处理运行时权限申请,确保存储访问安全;
通过View绑定实现UI交互逻辑;采用NestedScrollView解决小屏幕设备的内容滚动问题;
使用Shape Drawable创建自定义输入框和按钮样式;实现密码可见性切换功能时运用了InputType动态修改技术;
通过Intent实现页面跳转;采用单例模式管理当前用户状态;使用Assets资源加载和JSON解析技术初始化宠物数据。
3. 页面详细介绍
这是一个宠物领养应用的登录页面,提供普通用户和管理员双模式登录功能。
页面设计简洁友好,顶部爪印图标和温馨文案营造宠物主题氛围。
核心功能包括:表单验证、密码可见切换、管理员登录切换、数据初始化等。
业务逻辑上实现了三种登录路径:管理员硬编码验证、普通用户数据库验证和新用户注册跳转。
首次启动时会从assets加载宠物JSON数据到数据库,采用权限管理保障数据安全,使用Toast提供操作反馈,登录成功后通过CurrentUserUtils保存会话状态并跳转对应主页。
管理员
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 标题栏 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@color/primary">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="管理员页面"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- 数据统计卡片 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:background="@drawable/bg_border"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="宠物数据统计"
android:textColor="@color/gray_800"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_pet_count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="当前宠物总数: 0"
android:textColor="@color/gray_700"
android:textSize="14sp" />
</LinearLayout>
<!-- 数据管理卡片 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_border"
android:layout_marginBottom="16dp"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:text="宠物数据管理"
android:textColor="@color/gray_800"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_import_data"
android:layout_width="0dp"
android:layout_height="42dp"
android:layout_marginEnd="8dp"
android:layout_weight="1"
android:background="@drawable/bg_button_outline_blue"
android:text="更新预设"
android:textColor="#2196F3" />
<Button
android:id="@+id/btn_add_pet"
android:layout_width="0dp"
android:layout_height="42dp"
android:layout_weight="1"
android:background="@drawable/bg_button_outline_green"
android:text="添加宠物"
android:textColor="#4CAF50" />
</LinearLayout>
</LinearLayout>
<!-- 宠物列表标题 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:text="宠物列表"
android:textColor="@color/gray_800"
android:textSize="16sp"
android:textStyle="bold" />
<!-- 宠物列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_pet_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:clipToPadding="false" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<!-- 退出登录按钮 -->
<Button
android:id="@+id/btn_logout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:background="@drawable/bg_button_primary"
android:text="退出登录" />
</LinearLayout>
1. 页面的结构
该管理员页面采用经典的顶部标题栏+中部内容区+底部操作栏的三段式结构。
顶部为蓝色背景的标题栏,中部使用可滚动的NestedScrollView包裹数据统计卡片、管理功能区和宠物列表三部分,底部固定退出登录按钮。
数据统计区展示宠物总数,功能区提供数据更新和添加宠物操作,列表区采用RecyclerView展示所有宠物信息。
整体布局层次清晰,功能分区明确,重要操作按钮位置合理,符合管理后台类页面的设计规范。
2. 使用到的技术
该页面综合运用了多种Android核心技术:使用RecyclerView实现高性能列表展示;
通过AlertDialog构建二次确认弹窗;
采用NestedScrollView确保内容可滚动;
利用Shape Drawable创建卡片边框样式;
通过Intent实现页面跳转和数据传递;
使用Assets资源加载和JSON解析技术更新数据;
采用适配器模式处理列表数据绑定;
运用对话框交互提升操作安全性;
通过数据库CRUD操作管理宠物信息;
使用生命周期方法实现数据自动刷新。
3. 页面详细介绍
这是宠物领养系统的管理员控制台,提供全面的数据管理功能。
页面顶部显示管理员标识,中部展示核心数据看板和操作入口。
主要功能包括:实时统计宠物总量、从预设文件更新数据、添加新宠物、查看/编辑/删除现有宠物等。
采用列表形式展示所有宠物信息,支持点击查看详情或长按操作。
所有删除操作都需二次确认,数据变更后自动刷新显示。底部提供显眼的退出登录按钮,确保管理员可安全退出。
整体交互设计注重操作效率和数据安全,符合后台管理系统的专业要求。
首页
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 顶部导航 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="萌宠之家"
android:textColor="@color/gray_800"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
<!-- 轮播图 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="160dp"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="8dp">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager_banner"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/ll_dots"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_margin="16dp"
android:orientation="horizontal" />
</RelativeLayout>
<!-- 领养须知 -->
<LinearLayout
android:id="@+id/ll_adoption_guide"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="12dp"
android:background="@drawable/bg_adoption_guide"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="12dp">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
app:shapeAppearance="@style/CircleImageView"
android:layout_marginEnd="12dp"
android:padding="8dp"
android:src="@drawable/ic_info"
app:tint="@color/primary" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="领养须知"
android:textColor="@color/gray_800"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="了解领养流程及注意事项"
android:textColor="@color/gray_600"
android:textSize="12sp" />
</LinearLayout>
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_right"
app:tint="@color/gray_400" />
</LinearLayout>
<!-- 热门领养 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="热门领养"
android:layout_marginBottom="12dp"
android:textColor="@color/gray_800"
android:textSize="16sp"
android:textStyle="bold" />
<!-- 宠物列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_hot_pets"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
1. 页面的结构
该首页采用垂直滚动布局,顶部为应用名称标题栏。
中部包含三个核心模块:轮播图展示区采用ViewPager2实现图片自动切换,下方配有指示点。
领养须知卡片区使用图文结合方式展示重要信息。底部是热门领养列表,采用RecyclerView横向滑动展示宠物信息。
整体布局层次分明,重要内容突出显示,交互元素位置合理。各模块间留有适当间距,视觉上既保持连贯性又区分明确。
2. 使用到的技术
页面运用了多种现代Android开发技术。通过ViewPager2实现流畅的轮播图效果,配合Handler实现自动轮播功能。
采用RecyclerView高效展示热门宠物列表,避免内存浪费。使用AlertDialog构建领养确认弹窗,确保操作安全性。
通过Shape Drawable创建自定义圆点指示器。利用SharedPreferences管理用户登录状态。
采用异步加载方式处理宠物数据,保证界面流畅性。通过Intent实现页面跳转和数据传递。
3. 页面详细介绍
这是宠物领养应用的主页,为用户提供核心功能入口。
轮播图区域展示精选宠物,自动切换并支持手动滑动。领养须知卡片醒目提示重要流程信息,点击可查看详情。
热门领养列表展示待领养宠物,支持点击查看详情和直接申请领养。所有领养操作需二次确认,确保用户操作意图明确。
页面会在每次显示时自动刷新数据,保证信息时效性。
整体设计以用户友好为核心,操作流程简洁直观,视觉风格清新统一。
五、项目源码
👇👇👇👇👇快捷方式👇👇👇👇👇