1. 简介
上次更新日期:2022 年 3 月 30 日
用于远程调试、自动生成偏好设置界面和 Wizard-of-Oz 原型的库
是不是厌倦了那种在动画中调整了一个值,还要花好几分钟时间等待编译完成才能看到更改效果的糟心体验?有没有这样的想法:将原型交给别人,让他们使用您可以即时调整的各种选项来体验这个原型的不同特性?当有人提到“单行代码解决方案”时,您会不会感到不自在?如果是这样,Tweakr 或许正好适合您使用!
Tweakr 是一种 Android 库,可让您在代码中注解各种字段和方法,然后自动生成界面,从而以本地或远程方式更改相应元素。它可以使用 Firebase 和基于网络的界面即时更改应用中的值和相关设置。它还可以使用手机本地的 SharedPreferences 自动生成偏好设置界面屏幕。
简而言之,编写一行代码就能搞定:只需使用 @Tweak 为您想更改的内容添加注解,该库就会为您完成其余工作!
构建内容
在此 Codelab 中,您将构建一个简单的 Android 应用。您的应用将:
- 在屏幕上绘制一些文本和图片。
- 使用 @Tweakr 注解为应用中的字段和方法添加注解。
- 使用 Firebase 连接到 Tweakr 网页界面(网页界面已为您构建,随时可供使用)。
- 使用 Tweakr 操控视图并在屏幕上移动它们。
学习内容
- 如何为 Android 应用设置 Firebase。
- 如何为应用中的字段和方法添加注解,让 Tweakr 能够生成界面以对其进行控制。
此 Codelab 重点介绍如何使用 Tweakr 库。对于不相关的概念,我们仅会略作介绍,但是会提供不相关的代码块供您复制和粘贴。
所需条件
- 一台安装了 Android Studio 的计算机。
- 具备 Kotlin 和 Android View 方面的基础知识
2. 创建和设置 Firebase 项目
Tweakr 可以创建界面,这些界面可以使用 Firebase 自动将您的 Android 应用附加到网页界面。首先,您需要设置一个 Android 版 Firebase 项目。
创建 Firebase 项目
- 登录 Firebase。
- 在 Firebase 控制台中,点击 Add Project(或 Create a project),然后将您的 Firebase 项目命名为
Tweakr-Codelab
。 - 点击各个项目创建选项。如果系统提示,请接受 Firebase 条款。跳过设置 Google Analytics(分析)的步骤,因为您不会对此应用使用 Google Analytics(分析)。
如需详细了解 Firebase 项目,请参阅了解 Firebase 项目。
在 Firebase 中设置 Android 应用
- 在 Firebase 控制台中,使用您自己的软件包名称(例如
com.[your-domain].tweakr.sample)
)添加一个新的 Android 应用。 - 按照说明下载
google-services.json
文件。 - 将
google-services.json
文件复制到 Android 应用的app
模块目录中(例如tweakr-codelab/app/
)。 - 跳过确认与 Firebase 的连接的步骤。稍后,在您更新 Android 应用中的 ApplicationId 后,您会执行这项操作。
- 按照说明点击 Gradle Sync。
在控制台中启用 Firebase 产品
您所构建的应用会使用多个适用于 Web 应用的 Firebase 产品:
- Firebase Authentication 和 Firebase UI,可让用户轻松登录您的应用。
- Realtime Database,Tweakr 使用该数据库在您的应用和网页界面之间即时同步数据。
- Firebase 安全规则,用于保护您的数据库的安全。
其中一些产品需要进行特殊配置,或需要使用 Firebase 控制台启用。
为 Firebase Authentication 启用匿名登录
在此 Codelab 中,如需允许用户登录 Web 应用,您将使用匿名登录方法:
- 在 Firebase 控制台中,点击左侧面板中的 Build 下的 Authentication。
- 点击 Authentication,然后依次点击 Get Started -> Sign-in method 标签页(或点击此处直接进入“Sign-in method”标签页)。
- 点击登录提供程序列表中的 Anonymous,将 Enable 开关设置到开启位置,然后点击 Save。
启用 Realtime Database
Tweakr 使用 Realtime Database 每秒在您的应用和网页界面之间进行多次状态同步。
启用 Realtime Database:
- 在 Firebase 控制台的 Build 部分中,点击 Realtime Database。
- 点击 Create database。
- 选择数据库的位置(只需使用默认值即可)。请注意,此位置以后无法更改。
- 选择 Start in test mode 选项,确保在开发过程中可以随意向数据库写入数据。阅读有关安全规则的免责声明,然后点击 Next。
- 点击 Enable。
3. 构建 Android 示例应用
获取代码
我们已将此项目所需的所有内容放入 Git 代码库中。首先,您需要获取相关代码,然后在 Android Studio 中将其打开。
强烈建议:使用 Android Studio 导入代码库
- 打开 Android Studio,然后从 Version Control 中依次选择 File->New->Project。
- 选择
Git
作为版本控制选项。 - 输入网址
https://github.com/google/tweakr-codelab.git
。 - 点击 Clone。
更新 ApplicationId
由于 Firebase 需要您的 Android 应用的唯一 ApplicationId,因此您需要将示例重命名为您自己的 ApplicationId:
- 打开
Tweakr_codelab.app
模块的app/build.gradle
文件。 - 将
applicationId "com.yourdomain.tweakr.sample"
行更改为您在 Firebase 设置中指定的软件包名称。 - 点击 Sync,将您所做的更改同步到 Gradle 文件。
运行应用
- 点击 Run 即可编译并启动应用。如果您使用的是 Android 模拟器,请务必从 Google Play 库创建 AVD 映像,Firebase 需要这些映像。
您应该会在应用中看到一个简单的屏幕,其中会显示一些文本和一个圆圈。
- 点击文本即可触发动画。
4. 让我们开始 Tweakin'!
完成本部分后,您将能够从 Tweakr 网站远程控制应用中的视图!
添加 Tweakr 库依赖项
- 打开
settings.gradle
文件,并将 Jitpack 添加到代码库:
settings.gradle
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
- 打开
Tweakr_codelab.app
模块的app/build.gradle
文件,并添加 Tweakr 库依赖项:
app/build.gradle
dependencies {
...
// Required for local SharedPreferences or Firebase
implementation 'com.github.google.tweakr:core:2.2.2'
// Include this if you want Firebase support.
implementation 'com.github.google.tweakr:firebase:2.2.2'
}
- 点击 Sync Now 以同步 Gradle 更改。
初始化 Tweakr 代码库
首先,您需要在 SampleApplication 的 onCreate()
方法中初始化 Tweakr 代码库,以告知其使用 Firebase:
- 打开
SampleApplication.kt
文件。 - 取消注释内容为
Tweakr.setRepo(TweakrFirebaseRepo())
的代码行
这会告知 Tweakr 使用 TweakrFirebaseRepo
将其值同步到云端。TweakrFirebaseRepo
会自动使用默认 Firebase 实例(由您在第一部分中添加的 google-services.json
文件定义)。
进行一些调整
现在,您可以开始为应用的某些部分添加注解,以便 Tweakr 能够为其生成网页界面。
- 在
MainActivity.kt
文件中的fun animateText()
行上方,添加注解@Tweak
。这会告知 Tweakr 您想要远程控制此方法。
MainActivity.kt
@Tweak
fun animateText() {
introText.animate()
...
}
- 在
onCreate()
函数底部,添加Tweakr.register(this)
行。这会告知 Tweakr 解析相应类中的所有注解,并将其值与网络服务器同步。
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
introText = findViewById(R.id.text)
introText.setOnClickListener { animateText() }
Tweakr.register(this)
}
- 现在,再次运行应用。
如果一切顺利,Tweakr 此时已在后台完成初始化,并将相关调整与 Firebase 服务器同步。您将在下一部分中看到已完成的操作的神奇效果。
5. 调整网页界面中的值
现在,您已经在应用中设置了一些可使用 Tweakr 调整的值,接下来,您可以打开 Tweakr 网页界面来通过互联网远程控制这些值。如需开始调整应用中的值,最简单的方法就是使用 Tweakr 的预构建网站 Easyserver。此网站托管在 GitHub 上,并连接到您的 Firebase 数据库,以便同步值并从 Android 应用生成网页界面。
在 Firebase 中设置 Web 应用
首先,您需要在 Firebase 中设置 Web 应用,并向其授予 Easyserver 访问权限。
- 在 Firebase 控制台中,点击 Project Overview。
- 点击 Add app,然后选择 Web。
- 输入别名,然后点击 Register。
- 在 Add Firebase SDK 步骤中,复制
const firebaseConfig
及更高版本的所有内容。在下一步中,您要将其粘贴到 Tweakr Easyserver 中。
启动 Easyserver
- 访问 https://google.github.io/tflexibler/easyserver/,然后按照以下说明允许 Easyserver 访问您的 Firebase:
- 粘贴您在上一步中复制的
firebaseConfig
代码。
如果粘贴正确,它应该会显示您的唯一登录链接和 Let's get Tweakin' 按钮。
- 点击 Let's get Tweakin'。
您应该会看到一个 animateText() 按钮,该按钮以您之前注解的函数命名。
了解按钮
打开 Android 应用后,点击 Tweakr 网页界面中的 animateText() 按钮,然后观察手机屏幕。
哇,太神奇了!您应该看到相应文本执行了一些动画效果。这是怎么做到的呢?
您可能会问,如果这个按钮适用于无参数方法的话,那么如果我的方法接受参数,会发生什么情况?请参阅下一部分了解详情。
6. 包含参数的方法
Tweakr 还适用于包含一个参数的方法(尚不支持包含多个参数的方法)。我们来试试看:
- 在 MainActivity 类中,添加一个新方法来更改 TextView 中的文本:
MainActivity.kt
class MainActivity : Activity() {
...
@Tweak
fun setMessage(text: String) {
introText.text = text
}
...
- 请务必向新方法添加
@Tweak
注解。 - 再次运行应用,并观察 Tweakr Easyserver 网站如何使用文本字段调用相应方法,从而自动更新。
- 在文本字段中输入一些内容,然后实时观察应用有何变化!
远程控制方法固然不错,但 Tweakr 的真正强大之处在于更改代码中的字段值。更多乐趣尽在下一部分。
7. (可选)调整字段值
在 Android Studio 中,打开 CircleView.kt
文件。顶部似乎有一些用来控制圆圈的大小和位置的字段。我们来调整它们!
添加注解
- 在
centerX, centerY
和radius
字段上方添加@Tweak
注解。 - 此外,您还需要在对象初始化时调用
Tweakr.register()
,因此还要添加init()
方法。最后,您的代码应如下所示:
CircleView.kt
/** A View that draws a circle **/
class CircleView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
@Tweak
var centerX = 180f
@Tweak
var centerY = 180f
@Tweak
var radius = 50f
init {
Tweakr.register(this)
}
...
这样一来,Tweakr 就可以更改字段了,但您的任务还没结束。由于这是一个直接绘制到画布的自定义 View,因此当 Tweakr 更改字段的值时,该 View 不会自动使用新值重新绘制。每当 Tweakr 同步更改时,您都必须指示 View 重新绘制。
- 向 Tweakr 注册监听器,以便每当字段值以远程方式发生更改时,您都能收到监听器的通知。
为了避免发生内存泄漏,您还需要在 View 不使用监听器时使用 attachedToWindow
事件将监听器移除:
监听 Tweakr 值更改
使用对 Tweakr.addListener(this)
的调用替换 onAttachedToWindow()
方法,然后在 onDetachedFromWindow()
中移除监听器:
CircleView.kt
/** A View that draws a circle **/
class CircleView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr), TweakrRepo.OnChangeListener
{
...
override fun onAttachedToWindow() {
super.onAttachedToWindow()
// Register onFieldChanged() to redraw when any value changes.
Tweakr.addListener(this)
}
override fun onDetachedFromWindow() {
Tweakr.removeListener(this)
super.onDetachedFromWindow()
}
override fun onFieldChanged(name: String?, value: Any?) {
// This is called whenever a field's value is changed in Tweakr's UI.
// We could be granular here and check the name to match only the fields
// we care about, but for this demo it's simple enough to just redraw
// whenever *any* value changes.
invalidate()
}
...
(由于您将 this
设置为监听器,因此您还需要确保我们的类会扩展/实现 TweakrRepo.OnChangeListener
接口。)
试试看
现在,您可以开始体验了。运行应用,然后观察 Tweakr Easyserver 网站使用要调整的新字段进行自动更新。
8. 恭喜
恭喜,您已成功使用 Tweakr 构建了第一个应用!
您学习了如何使用 @Tweak
注解为方法和字段添加注解,如何对包含这些字段的对象调用 Tweakr.register()
,以及更高级的用法,即监听 Tweakr 更改事件以手动重新绘制 View。
您可以利用这些技能加快原型设计工作流程:在进行用户体验研究、用户研究等工作时即时更改动画值、远程控制 Wizard-of-Oz 原型。我们团队的一种常见用法是将动画原型 APK 分享给动画设计师,将 Tweakr 网络界面链接发送给设计师,让他们根据自己的喜好调整动画值。(这些动画设计师希望动画值能够非常精确!)
我们团队还针对微互动、手势和触感反馈创建原型,并与团队分享 Tweakr 链接以及相关设计的各种配置和选项,以便团队成员能够随意切换。然后,我们会创建一个共享文档,并让团队成员填写他们最喜欢的 Tweakr 值,这有助于我们先就设计达成共识,然后再在正式版中实现。
后续操作
其他可尝试的操作
- Wizard-of-Oz 远程控制:尝试在您的 activity 中创建一个在应用中获取屏幕名称枚举的方法。当 Tweakr 调用该方法时,加载与屏幕名称对应的新 fragment。这样一来,您只需在 Tweakr 网页界面中点击所需的屏幕,使用手机查看该应用的所有用户都会看到相应的新 fragment。这非常适合在用户调查中使用!
- 多用户:默认情况下,Tweakr 网页界面会同时向使用应用的所有用户同步更改。但有时,如果您有多个并发用户,您会希望每个用户都有自己的会话,从而让他们在界面中进行的所有调整都只会影响他们的手机,而不会影响其他用户的手机。请参阅 TweakrFirebaseRepoMultiuser 文档,了解如何使用
getUserKey().
创建多个会话 - 本地 PreferenceScreen:Tweakr 并非必需使用 Firebase。它还可以自动生成 Android 偏好设置界面,让您能够在手机上以本地方式更改设置。请参阅示例代码和文档。