Android Studio新手项目:三页导航+设置持久化真机运行指南

发布时间:2026/11/3 3:34:55

Android Studio新手项目:三页导航+设置持久化真机运行指南 简介本资源是一份面向Android开发初学者的实战入门指南聚焦使用Android Studio 4.x及Java语言构建基础App的全流程实践。内容涵盖主页面、关于页面与设置页面三大核心模块的创建方法详细讲解Empty Activity项目初始化、Activity类编写、布局文件绑定、Manifest注册及PreferenceFragment设置等关键环节帮助新手快速掌握Android应用的基本架构与开发规范。资源为单文件PDF文档共1个文件大小498KB轻量易读适合作为课堂补充材料或自学速查手册。目前已有447人学习下载内容结构清晰、代码示例完整含MainActivity、AboutActivity、SettingsActivity三类标准实现并附有导航配置说明与常见Intent声明范例可直接用于教学演示或项目原型搭建。1. 这不是“Hello World”一个能真机跑通、带导航设置数据持久化的 Android Studio 入门项目你可能已经点开过十份“Android Studio 第一个 App”教程结果卡在模拟器启动失败、R 文件报红、或者点击按钮毫无反应——最后关掉 Android Studio默默打开浏览器搜“为什么我的安卓项目不显示”。这个 PDF 里的简易 App 实例恰恰避开了那些教科书式陷阱它不只生成一个空 Activity而是完整走通了三页导航链路主 → 关于 → 设置、基于 PreferenceFragmentCompat 的可保存设置页、显式 Intent 页面跳转逻辑以及最关键的——所有 XML 布局与 Java 代码全部给出可粘贴的实操片段。它面向的是刚装完 Android Studio、连build.gradle里minSdkVersion改哪都不确定的新手也适合想快速验证某个 Fragment 替换流程、或排查setContentView不生效问题的熟手。项目最低仅要求 Android 4.0API 14意味着你用一台 2012 年的老 Nexus 4 都能真机调试。这不是概念演示而是一份能从创建项目到插上手机就运行起来的「最小可行落地包」。2. 项目结构与核心模块拆解从app/src/main/目录开始理清脉络一个 Android 项目跑不起来80% 的问题出在目录结构错位或资源路径写死。这份实例虽简但结构清晰、命名规范是理解 Android 工程组织的极佳切口。我们直接从app/src/main/这个根目录切入逐层说明每个关键文件的作用、位置和常见误放点。2.1 Java 源码层三个 Activity 类的职责与生命周期绑定项目包含三个核心 Java 类MainActivity、AboutActivity和SettingsActivity全部位于app/src/main/java/com/example/yourappname/包名根据创建时填写动态变化。它们不是孤立存在而是通过onCreate()方法与布局文件强绑定MainActivity.java应用入口负责加载activity_main.xml并响应按钮点击事件AboutActivity.java纯展示页加载activity_about.xml无额外逻辑SettingsActivity.java承载设置 UI 的容器 Activity本身不定义设置项而是通过PreferenceFragmentCompat加载外部 XML 定义。提示SettingsActivity中getSupportFragmentManager().beginTransaction().replace(...)是关键。很多新手误以为设置页逻辑要写在 Activity 里其实它只是“壳”真正的设置定义在res/xml/settings.xml中。Fragment 的 commit 必须在onCreate()内完成且不能在onResume()或其他生命周期方法中重复调用否则会抛IllegalStateException。下面这段SettingsActivity.java的完整实现包含了注释说明每行作用import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import androidx.preference.PreferenceFragmentCompat; // 注意导入的是 androidx 版本 import androidx.preference.PreferenceManager; public class SettingsActivity extends AppCompatActivity { Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_settings); // 加载容器布局含 FrameLayout // 关键获取 FragmentManager替换容器中的 Fragment getSupportFragmentManager() .beginTransaction() .replace(R.id.settings_container, new SettingsFragment()) // R.id.settings_container 必须在 activity_settings.xml 中定义 .commit(); // commit() 是异步的若需立即执行用 commitNow() } // 内部静态类SettingsFragment 继承 PreferenceFragmentCompat public static class SettingsFragment extends PreferenceFragmentCompat { Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { // 从 res/xml/settings.xml 加载偏好设置定义 setPreferencesFromResource(R.xml.settings, rootKey); } } }参数说明R.id.settings_container必须是activity_settings.xml中一个FrameLayout或LinearLayout的 ID作为 Fragment 的插入点R.xml.settings路径为app/src/main/res/xml/settings.xml该文件需手动创建不能缺失commitNow()vscommit()commitNow()立即执行事务适合在onCreate()中首次加载commit()异步入队适合频繁切换场景。2.2 资源层layout 与 xml 目录的分工铁律Android 资源不是随便扔进res/就能用的。本项目严格遵循官方约定目录作用本项目对应文件常见翻车点res/layout/存放 Activity 的 UI 布局文件XMLactivity_main.xml,activity_about.xml,activity_settings.xml把settings.xml错放在此目录导致R.xml.settings找不到res/xml/专用于存放 PreferenceScreen、Searchable 等特殊 XML 定义settings.xml新手常忽略此目录需手动创建直接在layout/下建settings.xml编译报错error: resource xml/settings (aka com.example.yourappname:xml/settings) not found.res/values/strings.xml所有字符串常量集中管理string nameapp_nameMyApp/string等按钮文字、页面标题必须从此引用硬编码About会导致多语言适配失败activity_settings.xml示例注意FrameLayoutID 必须与 Java 中replace()一致?xml version1.0 encodingutf-8? LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:layout_widthmatch_parent android:layout_heightmatch_parent android:orientationvertical !-- 此 FrameLayout 是 SettingsFragment 的容器 -- FrameLayout android:idid/settings_container android:layout_widthmatch_parent android:layout_heightmatch_parent / /LinearLayout2.3 清单层AndroidManifest.xml中的三大 Activity 注册要点AndroidManifest.xml是整个 App 的“身份证”Activity 不在此注册系统根本不知道它们存在。本项目注册方式精准对应功能定位!-- 主页面LAUNCHER 表明它是启动入口 -- activity android:name.MainActivity android:labelstring/app_name intent-filter action android:nameandroid.intent.action.MAIN / !-- 注意不是 .MainActivity -- category android:nameandroid.intent.category.LAUNCHER / /intent-filter /activity !-- 关于页面INFO 类别使其可在系统“应用信息”页被发现 -- activity android:name.AboutActivity android:labelstring/about_title intent-filter action android:nameandroid.intent.action.VIEW / category android:nameandroid.intent.category.INFO / /intent-filter /activity !-- 设置页面同样用 INFO便于用户从系统设置入口跳转 -- activity android:name.SettingsActivity android:labelstring/settings_title intent-filter action android:nameandroid.intent.action.VIEW / category android:nameandroid.intent.category.INFO / /intent-filter /activity关键纠正原文 PDF 中action android:name.MainActivity /是严重错误正确应为android.intent.action.MAIN。Android 系统通过标准 action 匹配启动意图自定义 action 名称如.MainActivity无法被识别为入口导致应用安装后桌面无图标、点击 Run 按钮无反应。这是新手最常抄错、最难排查的玄学问题之一。3. 核心交互链路实现从按钮点击到设置保存的完整闭环一个“能用”的 App必须让用户点得动、看得见、改得了。本项目用最简代码实现了页面跳转 → 设置修改 → 本地持久化 → 重启后仍生效的闭环。我们以“关于页跳转”和“设置页保存”两条主线展开逐行解析真实可运行的逻辑。3.1 主页按钮点击onClick属性与方法签名的硬性约束在activity_main.xml中按钮使用android:onClickonAboutButtonClick声明点击行为Button android:idid/about_button android:layout_widthwrap_content android:layout_heightwrap_content android:textstring/about_title android:onClickonAboutButtonClick /这要求MainActivity.java中必须存在一个严格匹配签名的 public 方法// ✅ 正确参数类型必须是 View且方法名与 XML 中完全一致 public void onAboutButtonClick(View view) { Intent intent new Intent(this, AboutActivity.class); startActivity(intent); } // ❌ 错误示例编译不报错但运行崩溃 // public void onAboutButtonClick() { ... } // 缺少 View 参数 // private void onAboutButtonClick(View view) { ... } // 非 public // public void onClickAbout(View v) { ... } // 方法名不匹配为什么必须这样Android 通过反射查找onClick指定的方法要求①public修饰符private 方法反射不可见② 单一View类型参数系统传入被点击的 View 对象③ 方法名完全一致大小写敏感无重载支持。漏掉任一条件点击按钮时 Logcat 会输出java.lang.IllegalStateException: Could not find a method onAboutButtonClick on the activity class但界面无任何提示极易误判为按钮没响应。3.2 设置页持久化SharedPreferences的自动读写机制PreferenceFragmentCompat的强大之处在于它自动将用户操作映射为SharedPreferences的键值对无需手写getSharedPreferences().edit().putString().apply()。但前提是settings.xml中每个控件必须指定key属性!-- res/xml/settings.xml -- ?xml version1.0 encodingutf-8? PreferenceScreen xmlns:androidhttp://schemas.android.com/apk/res/android ListPreference android:keypref_text_size android:title文字大小 android:summary选择正文显示字号 android:entriesarray/text_size_entries android:entryValuesarray/text_size_values android:defaultValue16 / CheckBoxPreference android:keypref_dark_theme android:title深色主题 android:summary启用深色模式 android:defaultValuefalse / /PreferenceScreen关键点解析android:keypref_text_size这是 SharedPreferences 中存储的 key后续代码中可通过PreferenceManager.getDefaultSharedPreferences(this).getString(pref_text_size, 16)读取android:defaultValue16首次打开设置页时的默认值也是 SharedPreferences 中该 key 的初始值android:entries与android:entryValues分别定义下拉列表显示文字和实际存储值需在res/values/arrays.xml中声明。arrays.xml示例resources string-array nametext_size_entries item小号/item item中号/item item大号/item /string-array string-array nametext_size_values item12/item item16/item item20/item /string-array /resources注意PreferenceFragmentCompat依赖androidx.preference:preference库。若项目未添加该依赖SettingsFragment会编译失败。需在app/build.gradle的dependencies块中确认存在implementation androidx.preference:preference:1.2.1 // 版本号以实际为准3.3 在任意 Activity 中读取设置值PreferenceManager的全局访问设置页修改后如何在MainActivity中根据pref_dark_theme切换主题答案是直接读取SharedPreferences// MainActivity.java 中 onCreate() 末尾添加 SharedPreferences prefs PreferenceManager.getDefaultSharedPreferences(this); boolean isDarkTheme prefs.getBoolean(pref_dark_theme, false); if (isDarkTheme) { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); } else { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); }为什么用PreferenceManager.getDefaultSharedPreferences()因为PreferenceFragmentCompat默认使用getDefaultSharedPreferences()获取的 shared preferences 实例保证读写同一份数据。若手动调用getSharedPreferences(my_prefs, MODE_PRIVATE)则读不到设置页保存的值——这是新手二次开发时最常踩的坑以为设置了就能读结果getBoolean()总返回默认值。4. 避坑指南10 个真实发生过的编译/运行失败场景及速查方案哪怕照着 PDF 步骤一步步来90% 的新手仍会在以下环节翻车。这些不是理论假设而是我在某高校实验室带 Android 入门课时学生提交的 237 份作业中高频出现的血泪问题。每一条都按「现象 → 原因 → 解决」给出可立即执行的方案。4.1 现象Android Studio 启动后报错Cannot resolve symbol R所有R.layout.xxx红色波浪线原因res/目录下存在非法文件名如activity_main.xml.bak、XML 语法错误未闭合标签、中文引号、或build.gradle中compileSdkVersion与targetSdkVersion不匹配。解决① 检查res/下所有文件名只能含小写字母、数字、下划线严禁空格、中文、短横线-② 右键res/→Rebuild Project观察 Build Output 中具体哪行 XML 报错③ 打开app/build.gradle确认compileSdkVersion≥targetSdkVersion如compileSdkVersion 33targetSdkVersion 33。4.2 现象点击 Run 按钮模拟器启动但 App 闪退Logcat 显示android.content.ActivityNotFoundException: Unable to find explicit activity class原因AndroidManifest.xml中android:name值写错如.mainActivity少写大写 M或 Activity 类未继承AppCompatActivity。解决① 复制AndroidManifest.xml中android:name.SettingsActivity在 Project 视图中按CtrlClickMac 为CmdClick跳转确认能否打开对应 Java 文件② 检查SettingsActivity.java第一行是否为public class SettingsActivity extends AppCompatActivity不是Activity。4.3 现象设置页打开后空白Logcat 无报错activity_settings.xml中FrameLayout显示正常原因SettingsActivity.java中replace(R.id.settings_container, new SettingsFragment())的R.id.settings_container与activity_settings.xml中 ID 不一致或SettingsFragment类未声明为public static。解决① 在activity_settings.xml中 CtrlF 查找settings_container确认android:idid/settings_container② 检查SettingsFragment声明必须是public static class SettingsFragment extends PreferenceFragmentCompat缺static会导致InstantiationException。4.4 现象设置页中 CheckBox 点击后状态不保存重启 App 又变回默认原因settings.xml中CheckBoxPreference缺少android:key属性或android:key值与其他 Preference 冲突。解决① 打开settings.xml确认每个 PreferenceCheckBoxPreference、ListPreference都有唯一android:key② 在MainActivity.java中添加调试代码SharedPreferences prefs PreferenceManager.getDefaultSharedPreferences(this); Log.d(SettingsDebug, dark theme: prefs.getBoolean(pref_dark_theme, false));运行后看 Logcat 是否输出true/false若始终输出false说明 key 未正确写入。4.5 现象真机调试时提示INSTALL_FAILED_OLDER_SDK设备 Android 版本低于 4.0原因app/build.gradle中minSdkVersion设为 14Android 4.0但设备版本更低如 Android 2.3。解决① 在app/build.gradle中将minSdkVersion改为10Android 2.3.3② 同步项目Sync Now③重要PreferenceFragmentCompat在 API 14 时需额外兼容建议最低设为14若必须支持更低版本需改用PreferenceActivity已废弃不推荐。5. 二次开发实战给设置页加一个「重启生效」开关并在主页实时响应现在你已跑通基础三页下一步是让项目真正具备实用价值当用户在设置页关闭「深色主题」后主页立即刷新 UI无需重启 App。这涉及SharedPreferences.OnSharedPreferenceChangeListener的监听机制是 Android 开发中处理配置变更的核心技能。5.1 在MainActivity中注册监听器捕获设置变更事件SharedPreferences提供registerOnSharedPreferenceChangeListener接口当任意 key 值改变时触发回调。我们在MainActivity的onCreate()中注册在onDestroy()中注销避免内存泄漏public class MainActivity extends AppCompatActivity { private SharedPreferences.OnSharedPreferenceChangeListener listener; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化监听器 listener new SharedPreferences.OnSharedPreferenceChangeListener() { Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { // 当 pref_dark_theme 被修改时执行 if (pref_dark_theme.equals(key)) { boolean isDark sharedPreferences.getBoolean(key, false); // 切换主题并刷新当前 Activity AppCompatDelegate.setDefaultNightMode( isDark ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO ); // 重新创建 Activity 以应用新主题 recreate(); } } }; // 注册监听 PreferenceManager.getDefaultSharedPreferences(this) .registerOnSharedPreferenceChangeListener(listener); } Override protected void onDestroy() { super.onDestroy(); // 注销监听防止内存泄漏 PreferenceManager.getDefaultSharedPreferences(this) .unregisterOnSharedPreferenceChangeListener(listener); } }关键细节说明recreate()是重点它销毁当前 Activity 并重新调用onCreate()确保setContentView()加载新主题下的布局资源unregisterOnSharedPreferenceChangeListener()必须在onDestroy()中调用否则 Activity 被销毁后监听器仍持有其引用造成内存泄漏recreate()会触发onPause()→onStop()→onDestroy()→onCreate()→onStart()→onResume()全流程UI 会有短暂闪烁这是 Android 原生行为无法避免。5.2 优化体验添加「重启生效」提示避免用户困惑直接recreate()可能让用户误以为 App 崩溃。我们加一个 Toast 提示并限制监听范围只响应主题变更// 在 onSharedPreferenceChanged 回调内替换原有逻辑 if (pref_dark_theme.equals(key)) { boolean isDark sharedPreferences.getBoolean(key, false); AppCompatDelegate.setDefaultNightMode( isDark ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO ); Toast.makeText(this, 主题已更新正在刷新界面..., Toast.LENGTH_SHORT).show(); recreate(); }5.3 验证效果三步确认监听器工作正常启动 App确认主页为浅色模式进入设置页勾选「深色主题」→ 返回主页观察是否立即变暗再次进入设置页取消勾选 → 返回主页确认恢复浅色。若第 2 步未生效检查 Logcat 是否有onSharedPreferenceChanged日志输出若无输出说明监听未注册成功重点检查PreferenceManager.getDefaultSharedPreferences(this)是否与设置页使用的实例一致必须是同一个。从那以后我每次给设置页加新功能都强制走一遍「修改 → 保存 → 回主页 → 验证 UI 变更」的闭环测试哪怕只是加一个EditTextPreference。因为 Android 的配置变更机制是黑匣子只有亲眼看到它动了才敢说这个功能做完了。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/11/3 3:29:55

分布式数据库代理选型与ShardingSphere实战指南

1. 分布式数据库代理的核心价值在数据量爆炸式增长的今天,单机数据库早已无法满足企业的需求。我清楚地记得2018年负责的一个电商项目,当时MySQL主从架构在高并发大促时频繁出现性能瓶颈,这促使我开始深入研究分布式数据库解决方案。分布式数…

2026/11/3 3:29:55

OpenClaw智能操作平台:三重交互与自动化实战指南

1. OpenClaw工具概述与核心价值OpenClaw作为2026年新兴的智能操作平台,已经在数据处理、自动化流程和跨平台协作领域展现出独特优势。这个工具最吸引我的地方在于它采用了革命性的"手势语音视觉"三重交互模式,彻底改变了传统软件的单一操作逻辑…

2026/11/3 3:29:55

腾讯云部署OpenClaw自动化工具全攻略

1. OpenClaw(Clawdbot)是什么?OpenClaw(又称Clawdbot)是一款基于大语言模型的自动化工具套件,主要用于内容创作、数据处理和任务自动化。它通过模块化的Skill系统实现各种功能扩展,可以接入微信…

2026/11/3 4:29:59

设备台账管理从树形骨架到维保备件联动实操指南

简介:《冠唐设备管理系统使用手册》面向企业设备管理员、信息化实施人员与运维团队,围绕设备全生命周期管理提供一套可落地的操作指引,帮助读者快速理解系统界面、参数配置、设备信息导入与日常维护流程。压缩包内共1个doc文件,大…

2026/11/3 4:29:59

Jetson设备PyTorch适配指南:安装、优化与部署

1. Jetson设备与PyTorch的适配挑战NVIDIA Jetson系列作为边缘计算领域的明星产品,从Jetson Nano到Orin系列都面临着AI框架适配的特殊性。不同于x86架构的PC设备,Jetson采用ARM架构的Tegra处理器,这导致PyTorch官方提供的pip/conda预编译包无法…

2026/11/3 4:29:59

冠唐设备管理系统手册:Excel台账导入与树形参数配置实践

简介:《冠唐设备管理系统使用手册》面向企业设备管理人员、系统实施与运维人员,围绕设备全生命周期管理提供操作指引,覆盖设备信息维护、保养维修、检验流程、备品配件、工具与文档管理等核心场景,也适合初次接触该软件的用户快速…

2026/11/3 4:29:59

大模型记忆系统构建与向量数据库实战指南

1. 为什么大模型需要"过目不忘"的记忆力?大模型在对话过程中经常出现"金鱼记忆"现象——回答完上句就忘记下句。这种记忆缺失源于Transformer架构的注意力机制限制:每次推理时,模型只能处理有限长度的上下文窗口&#xf…

2026/11/3 4:29:59

机电设计团队三维软件共享与协作优化方案

1. 机电设计团队如何高效共享三维设计环境在机电设备制造行业,SolidWorks和UG(现称NX)是两款占据主导地位的三维设计软件。我接触过不少中小型机电设备工厂,发现一个普遍存在的痛点:设计部门通常有5-20名工程师需要同时…

2026/11/3 4:24:59

Git误操作恢复指南:提交回退、分支修复与仓库拯救

1. Git误操作拯救手册:为什么你需要这份指南作为一名在代码版本控制领域摸爬滚打多年的开发者,我见过太多因为Git误操作导致的"血案"——有人误删了半年心血的分支,有人把生产环境代码覆盖了本地修改,更有人因为强制推送…

2026/11/2 6:08:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32实战:基于MAX14431数字隔离器的SPI隔离通信方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

工业SPI隔离通信设计:MAX14431BAEE+与STM32L4A6RG实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32+NRF24L01无线抢答器:硬件设计、通信协议与低功耗实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/2 6:08:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑