安卓开发(冒泡篇)
Android Studio 技巧
- 导入已有项目(导入 app 文件夹的上一层)
- 所需的 gradle 和其 plugin 在
build.gradle
中查看(一般 gradle 是 7.4 版本,plugin 是 7.3.1 版本) - 更换 JDK 版本
- 所需的 gradle 和其 plugin 在
- 查看项目的内容可以使用 VSCode 的搜索功能
- 查看错误的方法
- 左下角 Run
- 左下角 Logcat
- 对于需要安装谷歌三件套的应用
- 设置 Theme.MaterialComponents.DayNight.NoActionBar 去除应用栏
- RelativeLayout 和 LinearLayout 的区别
- RelativeLayout 允许您根据相对位置来定位视图元素,而 LinearLayout 则按照您指定的方向(水平或垂直)来排列它们。例如,如果您希望在界面上放置一个按钮,使其位于屏幕正中间,您可以使用 RelativeLayout 来实现这一点。如果您希望在界面上放置多个按钮并按照一定的顺序排列它们,您可以使用 LinearLayout 来实现这一点。总的来说,RelativeLayout 更适合在界面中放置视图元素并定义它们之间的相对位置关系,而 LinearLayout 则更适合按照一定的顺序排列视图元素
- 不懂的问题问 ChatGPT
研究项目一【Weather app】
下载项目的 apk 进安卓手机中并测试运行
项目总览
- java
- com.example.weather
- listener【监听器】
- 设置 API KEY
- model【处理业务逻辑】
- service【处理 API 连接的服务,如当前天气、今后五天的天气等】
- ui【UI 界面】
- activity【处理应用程序的屏幕】
- fragment【处理用户界面部分】
- utils【实用工具类】
- ApiClient【标准代码:处理网络请求】
- AppUtil【标准代码:获取一天的开始时间或结束时间、向日历中添加天数等】
- Constants【关于内容的静态变量,如月份、语言等】
- DateConverter【标准代码:日期转换】
- DbUtil【获取天气】
- ElasticDragDismissFrameLayout【在 FrameLayout 的基础上增加了弹性拖动和可解除的功能】
- LocaleManager【改变地区、读取当前地区、更新语言等】
- MyApplication【初始化应用时要做的,如管理地区、暗黑模式等】
- SharedPreferencesUtil【检查是否开启暗黑模型和设置暗黑模式】
- SnackbarUtil【处理 Snackbar】
- TextViewFactory【处理 TextView】
- ViewAnimation【视觉动效】
- listener【监听器】
- com.example.weather
- res
- anim【滑动动效】
- drawable【存储资源文件】
- layout【UI 界面布局】
- menu【初始菜单】
- values【存储变量】
源码修改
- app\src\main\res\values\open_weather_map_api.xml 中的 KEY API
- KEY API 为 9884c93098d146643ecce096d6b9eb2d
- 获取城市的经纬度:http://api.openweathermap.org/geo/1.0/direct?q=zhuhai&limit=5&appid=9884c93098d146643ecce096d6b9eb2d
- 获取经纬度的天气:https://api.openweathermap.org/data/2.5/weather?lat=22.273734&lon=113.5721327&appid=9884c93098d146643ecce096d6b9eb2d
① 从 AndroidManifest.xml 出发
首先一定要加 <uses-permission android:name="android.permission.INTERNET" />
用于联网
application 里接 android:name=".utils.MyApplication" 大概是初始化执行的
application 有很多 activity,每个 activity 都有 android:name 对应不同逻辑
这个项目加载了三个:
- .ui.activity.HourlyActivity
- .ui.activity.MainActivity【内容最多,应该是主体】
- .ui.activity.BaseActivity
- PS:前两个是基于第三个类的扩展
② 细看 MainActivity
一般 setContentView 接的就是一开始加载的页面,但这里有点特殊:
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// 相当于
setContentView(R.layout.activity_main);
setSupportActionBar(binding.toolbarLayout.toolbar) 是右上角的搜索栏(toolbar.xml)
initSearchView() 负责处理搜索栏中的数据,用于跳转
initValues() 用于初始化变量(用到了 model/db 文件夹中的类,几个函数没看懂干啥的)
③ 懒得看了,完全看不懂~
跟做项目二【Blood Donation App】
官网把项目删了,找到个类似的项目:Blood-Point-App
但这个项目运行不了,只好跟着视频一步步做了
① 第一、二集
主要干了:
- 做个 app 开机进入页面和登入页面(两个 xml 和两个 java 后台逻辑文件)
- 做了个页面进入的动画(实现了两个页面直接的跳转)
主函数改名字成 SplashScreenActivity,xml 改成 activity_splash_screen
去掉了页面栏,values 的 themes 的 DarkActionBar 改成 NoActionBar
新建了个文件夹叫 anim,存储动画(bottom_animation.xml 和 top_animation.xml)
PS:创建了一个官方的 activity_login.xml 的布局文件,测试后发现能够实现用户名和密码自动保存的功能,似乎 SharePrefernces 也能做到
② 第三集
主要干了:
- 完善了简单的登入页
- 做了个注册页(SelectRegistrationActivity)
- 做个捐献者注册页(DonorRegistrationActivity)
- 做个接受者注册页(RecipientRegistrationActivity)
PS:逻辑是登入页 -> 注册页 -> 捐献者注册页/接受者注册页 -> 登入页 -> 进入主页面
注意创建页面时,一般在后台逻辑那里创建,会自动创建页面【Activity -> Empty Activity】
如果创建单独页面(无后台逻辑),则是【Layout Resource File】
按钮的背景 drawable/buttons_background
改了 build.gradle,如下:
android {
defaultConfig {
multiDexEnabled true
}
}
dependencies {
implementation "androidx.cardview:cardview:1.0.0"
implementation 'com.google.android.material:material:1.4.0'
implementation 'com.android.support:multidex:1.0.3'
implementation 'de.hdodenhof:circleimageview:3.1.0'
}
改了 values/style、strings、colors,如下:
<!-- colors -->
<resources>
<color name="colorPrimary">#Be5025</color>
</resources>
<!-- strings -->
<resources>
<string name="app_name" translatable="false">Blood Point</string>
<string name="navigation_drawer_open" translatable="false">Open navigation drawer</string>
<string name="navigation_drawer_close" translatable="false">Close navigation drawer</string>
<string-array name="bloodgroups">
<item>Select your blood group</item>
<item>A+</item>
<item>A-</item>
<item>B+</item>
<item>B-</item>
<item>AB+</item>
<item>AB-</item>
<item>O+</item>
<item>O-</item>
</string-array>
</resources>
<!-- style -->
<resources>
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
</style>
<style name="TextInputlayoutStyle" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<item name="boxStrokeColor">#fff</item>
<item name="boxStrokeWidth">2dp</item>
</style>
</resources>
Spinner 似乎是选择器,在 string-array 中放了很多 string item
ScrollView 是滚动条,防止屏幕尺寸不一,为了显示全部组件增加的右侧边滚动条(对于开头代码,整体添加还是蛮好的)
③ 第四集
主要干了:
- 完善了全部的登入页
不知道为啥,加上了下面两个代码,右侧视图就不显示了:
- android:theme="@style/TextInputlayoutStyle"
- app:hintTextAppearance="@color/colorPrimary"
④ 第五、六集
主要干了:
- 注册了 Firebase
- 完善了捐献者注册页
- 完善了接受者注册页
获取开发版 SHA(cmd,密钥为 android):
cd C:\Users\LILANJUN\.android
keytool -list -v -keystore debug.keystore
关于更改 build gradle 的报错参考这篇文章,总结如下:
- settings.gradle 修改如下
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
/*
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
*/
rootProject.name = "android_2"
include ':app'
- build.gradle 修改如下
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
// Make sure that you have the following two repositories
google()
mavenCentral() // Maven Central repository
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.1'
classpath 'com.google.gms:google-services:4.3.13'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
// Make sure that you have the following two repositories
google() // Google's Maven repository
mavenCentral() // Maven Central repository
jcenter() // Warning: this repository is going to shut down soon
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
除了修改代码,还额外需要:
- Android Studio 下载 firebase SDK 插件:Auth、Realtime 和 Cloud Storage
- firebase 改规则:Auth 启用(邮件 + 密码)、Real 和 Storage
# 注意 Storage 的规则如下
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
注意此时启动 APP 要用 VPN!!
⑤ 第七集
主要干了:
- 完善了登入页的后台逻辑
- 做了个主页面
登入页的逻辑是:如果已经登入了(判断当前的用户状态)就进入主页面,否则还是登入页
⑥ 第八、九集
主要干了:
- 完善了主页面
- 做了个左侧可伸缩菜单页
- 做了个显示个人信息页