Skip to content

Commit 3663495

Browse files
authored
Merge pull request #101 from rive-app/96
96
2 parents ac17961 + e60b1a7 commit 3663495

File tree

7 files changed

+288
-34
lines changed

7 files changed

+288
-34
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- name: Build Android
1919
uses: reactivecircus/android-emulator-runner@v2
2020
with:
21-
api-level: 29
21+
api-level: 30
2222
script: ./gradlew kotlin:assembleRelease
2323
- name: Upload artifact
2424
uses: actions/upload-artifact@v2
@@ -55,7 +55,7 @@ jobs:
5555
- name: Publish to MavenCentral
5656
uses: reactivecircus/android-emulator-runner@v2
5757
with:
58-
api-level: 29
58+
api-level: 30
5959
script: ./gradlew publishAllPublicationsToSonatypeRepository --max-workers 1 closeAndReleaseSonatypeStagingRepository
6060
env:
6161
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ This is the Android runtime for [Rive](https://rive.app), currently in beta. The
1313
To add Rive in your project, include the following in your `dependencies`:
1414

1515
```
16-
implementation 'app.rive:rive-android:0.0.2'
16+
implementation 'app.rive:rive-android:0.0.4'
1717
```
1818

1919
## RiveAnimationView

app/src/main/java/app/rive/runtime/example/AndroidPlayerActivity.kt

Lines changed: 214 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
package app.rive.runtime.example
22

3+
import android.graphics.Color
34
import android.os.Bundle
45
import android.view.Gravity
56
import android.view.View
67
import android.widget.*
78
import androidx.appcompat.app.AppCompatActivity
89
import androidx.appcompat.widget.AppCompatButton
10+
import androidx.appcompat.widget.AppCompatCheckBox
11+
import androidx.appcompat.widget.AppCompatEditText
912
import app.rive.runtime.kotlin.RiveAnimationView
1013
import app.rive.runtime.kotlin.RiveDrawable.Listener
1114
import app.rive.runtime.kotlin.core.*
1215

1316
class AndroidPlayerActivity : AppCompatActivity() {
1417
var loop: Loop = Loop.NONE
1518
var direction: Direction = Direction.AUTO
19+
var playButtonMap: HashMap<String, View> = HashMap()
20+
var pauseButtonMap: HashMap<String, View> = HashMap()
21+
var stopButtonMap: HashMap<String, View> = HashMap()
1622

1723
val animationResources = listOf(
1824
R.raw.artboard_animations,
@@ -22,13 +28,16 @@ class AndroidPlayerActivity : AppCompatActivity() {
2228
R.raw.flux_capacitor,
2329
R.raw.loopy,
2430
R.raw.mascot,
31+
R.raw.neostream,
2532
R.raw.off_road_car_blog,
2633
R.raw.progress,
2734
R.raw.pull,
2835
R.raw.rope,
36+
R.raw.skills,
2937
R.raw.trailblaze,
38+
R.raw.ui_swipe_left_to_delete,
3039
R.raw.vader,
31-
R.raw.wacky
40+
R.raw.wacky,
3241
)
3342

3443
val animationView by lazy(LazyThreadSafetyMode.NONE) {
@@ -44,6 +53,11 @@ class AndroidPlayerActivity : AppCompatActivity() {
4453
animationView.artboardName
4554
animationView.setRiveResource(animationResources[index], artboardName = null)
4655
setSpinner()
56+
57+
playButtonMap.clear()
58+
pauseButtonMap.clear()
59+
stopButtonMap.clear()
60+
4761
animationView.drawable.file?.firstArtboard?.name?.let {
4862
loadArtboard(it)
4963
}
@@ -92,25 +106,31 @@ class AndroidPlayerActivity : AppCompatActivity() {
92106
layout.gravity = Gravity.END
93107

94108
var text = TextView(this)
95-
text.setText(animationName)
109+
text.text = animationName
96110

97111
var playButton = AppCompatButton(this)
98-
playButton.setText(">")
112+
playButton.text = ">"
113+
playButton.background.setTint(Color.WHITE)
99114
playButton.setOnClickListener {
100115
animationView.play(animationName, loop, direction)
101116
}
117+
playButtonMap[animationName] = playButton
102118

103119
var pauseButton = AppCompatButton(this)
104-
pauseButton.setText("||")
120+
pauseButton.text = "||"
121+
pauseButton.background.setTint(Color.WHITE)
105122
pauseButton.setOnClickListener {
106123
animationView.pause(animationName)
107124
}
125+
pauseButtonMap[animationName] = pauseButton
108126

109127
var stopButton = AppCompatButton(this)
110-
stopButton.setText("[]")
128+
stopButton.text = "[]"
129+
stopButton.background.setTint(Color.RED)
111130
stopButton.setOnClickListener {
112131
animationView.stop(animationName)
113132
}
133+
stopButtonMap[animationName] = stopButton
114134

115135

116136
layout.addView(text)
@@ -120,12 +140,128 @@ class AndroidPlayerActivity : AppCompatActivity() {
120140
return layout
121141
}
122142

143+
144+
fun addStateMachineControl(artboard: Artboard, stateMachineName: String): List<View> {
145+
val views = mutableListOf<View>()
146+
val layout = LinearLayout(this)
147+
layout.orientation = LinearLayout.HORIZONTAL
148+
layout.gravity = Gravity.END
149+
150+
val text = TextView(this)
151+
text.text = stateMachineName
152+
153+
val playButton = AppCompatButton(this)
154+
playButton.text = ">"
155+
playButton.background.setTint(Color.WHITE)
156+
playButton.setOnClickListener {
157+
animationView.play(stateMachineName, loop, direction, isStateMachine = true)
158+
}
159+
playButtonMap[stateMachineName] = playButton
160+
161+
val pauseButton = AppCompatButton(this)
162+
pauseButton.text = "||"
163+
pauseButton.background.setTint(Color.WHITE)
164+
pauseButton.setOnClickListener {
165+
animationView.pause(stateMachineName, isStateMachine = true)
166+
}
167+
pauseButtonMap[stateMachineName] = pauseButton
168+
169+
val stopButton = AppCompatButton(this)
170+
stopButton.text = "[]"
171+
stopButton.background.setTint(Color.RED)
172+
stopButton.setOnClickListener {
173+
animationView.stop(stateMachineName, isStateMachine = true)
174+
}
175+
stopButtonMap[stateMachineName] = stopButton
176+
177+
val stateMachine = artboard.stateMachine(stateMachineName)
178+
179+
layout.addView(text)
180+
layout.addView(playButton)
181+
layout.addView(pauseButton)
182+
layout.addView(stopButton)
183+
views.add(layout)
184+
185+
186+
stateMachine.inputs.forEach {
187+
val layout = LinearLayout(this)
188+
layout.orientation = LinearLayout.HORIZONTAL
189+
layout.gravity = Gravity.END
190+
191+
val text = TextView(this)
192+
text.text = it.name
193+
layout.addView(text)
194+
195+
if (it.isTrigger) {
196+
val triggerButton = AppCompatButton(this)
197+
triggerButton.text = "Fire"
198+
triggerButton.background.setTint(Color.WHITE)
199+
triggerButton.setOnClickListener { _ ->
200+
animationView.fireState(stateMachineName, it.name)
201+
}
202+
layout.addView(triggerButton)
203+
}
204+
205+
if (it.isBoolean) {
206+
val boolBox = AppCompatCheckBox(this)
207+
if ((it as StateMachineBooleanInput).value) {
208+
boolBox.isChecked = true
209+
}
210+
boolBox.setOnCheckedChangeListener { _, b ->
211+
animationView.setBooleanState(stateMachineName, it.name, b)
212+
}
213+
layout.addView(boolBox)
214+
}
215+
216+
if (it.isNumber) {
217+
val editText = AppCompatEditText(this)
218+
editText.setText((it as StateMachineNumberInput).value.toString())
219+
val editTriggerButton = AppCompatButton(this)
220+
editTriggerButton.text = "Apply"
221+
editTriggerButton.background.setTint(Color.WHITE)
222+
editTriggerButton.setOnClickListener { _ ->
223+
try {
224+
var value = editText.text.toString().toFloat()
225+
animationView.setNumberState(stateMachineName, it.name, value)
226+
} catch (e: Error) {
227+
228+
}
229+
}
230+
231+
layout.addView(editText)
232+
layout.addView(editTriggerButton)
233+
}
234+
235+
views.add(layout)
236+
}
237+
238+
return views
239+
}
240+
123241
fun loadArtboard(artboardName: String) {
124242
var controls = findViewById<LinearLayout>(R.id.controls)
125243
controls.removeAllViews()
126-
animationView.drawable.file?.artboard(artboardName)?.animationNames?.forEach {
127-
controls.addView(addAnimationControl(it))
244+
animationView.drawable.file?.artboard(artboardName)?.let { artboard ->
245+
if (artboard.stateMachineNames.size > 0) {
246+
val stateMachineHeader = TextView(this)
247+
stateMachineHeader.text = "State Machines:"
248+
controls.addView(stateMachineHeader)
249+
artboard.stateMachineNames.forEach {
250+
addStateMachineControl(artboard, it).forEach {
251+
controls.addView(it)
252+
}
253+
}
254+
}
255+
if (artboard.animationNames.size > 0) {
256+
val animationsHeader = TextView(this)
257+
animationsHeader.text = "Animations:"
258+
controls.addView(animationsHeader)
259+
artboard.animationNames.forEach {
260+
controls.addView(addAnimationControl(it))
261+
}
262+
}
128263
}
264+
129265
}
130266

131267
fun setSpinner() {
@@ -135,7 +271,7 @@ class AndroidPlayerActivity : AppCompatActivity() {
135271
this,
136272
android.R.layout.simple_spinner_dropdown_item,
137273
artboardNames
138-
);
274+
)
139275
dropdown.adapter = adapter
140276
dropdown.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
141277
override fun onItemSelected(
@@ -163,7 +299,7 @@ class AndroidPlayerActivity : AppCompatActivity() {
163299
this,
164300
android.R.layout.simple_spinner_dropdown_item,
165301
resourceNames
166-
);
302+
)
167303
dropdown.adapter = adapter
168304
dropdown.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
169305
override fun onItemSelected(
@@ -190,36 +326,92 @@ class AndroidPlayerActivity : AppCompatActivity() {
190326
val events = findViewById<LinearLayout>(R.id.events)
191327
val listener = object : Listener {
192328
override fun notifyPlay(animation: PlayableInstance) {
193-
val text = TextView(that)
194-
text.setText("Play ${(animation as LinearAnimationInstance).animation.name}")
195-
events.addView(text, 0)
329+
var text: String? = null
330+
if (animation is LinearAnimationInstance) {
331+
text = animation.animation.name
332+
} else if (animation is StateMachineInstance) {
333+
text = animation.stateMachine.name
334+
}
335+
text?.let {
336+
val textView = TextView(that)
337+
textView.text = "Play $text"
338+
events.addView(textView, 0)
339+
playButtonMap.get(text)?.let {
340+
it.background.setTint(Color.GREEN)
341+
}
342+
pauseButtonMap.get(text)?.let {
343+
it.background.setTint(Color.WHITE)
344+
}
345+
stopButtonMap.get(text)?.let {
346+
it.background.setTint(Color.WHITE)
347+
}
348+
}
196349
}
197350

198351
override fun notifyPause(animation: PlayableInstance) {
199-
val text = TextView(that)
200-
text.setText("Pause ${(animation as LinearAnimationInstance).animation.name}")
201-
events.addView(text, 0)
352+
var text: String? = null
353+
if (animation is LinearAnimationInstance) {
354+
text = animation.animation.name
355+
} else if (animation is StateMachineInstance) {
356+
text = animation.stateMachine.name
357+
}
358+
text?.let {
359+
val textView = TextView(that)
360+
textView.text = "Pause $text"
361+
events.addView(textView, 0)
362+
playButtonMap.get(text)?.let {
363+
it.background.setTint(Color.WHITE)
364+
}
365+
pauseButtonMap.get(text)?.let {
366+
it.background.setTint(Color.BLUE)
367+
}
368+
stopButtonMap.get(text)?.let {
369+
it.background.setTint(Color.WHITE)
370+
}
371+
}
202372
}
203373

204374
override fun notifyStop(animation: PlayableInstance) {
205-
val text = TextView(that)
206-
text.setText("Stop ${(animation as LinearAnimationInstance).animation.name}")
207-
events.addView(text, 0)
375+
var text: String? = null
376+
if (animation is LinearAnimationInstance) {
377+
text = animation.animation.name
378+
} else if (animation is StateMachineInstance) {
379+
text = animation.stateMachine.name
380+
}
381+
text?.let {
382+
val textView = TextView(that)
383+
textView.text = "Stop $text"
384+
events.addView(textView, 0)
385+
playButtonMap.get(text)?.let {
386+
it.background.setTint(Color.WHITE)
387+
}
388+
pauseButtonMap.get(text)?.let {
389+
it.background.setTint(Color.WHITE)
390+
}
391+
stopButtonMap.get(text)?.let {
392+
it.background.setTint(Color.RED)
393+
}
394+
}
208395
}
209396

210397
override fun notifyLoop(animation: PlayableInstance) {
211-
val text = TextView(that)
212-
text.setText("Loop ${(animation as LinearAnimationInstance).animation.name}")
213-
events.addView(text, 0)
398+
if (animation is LinearAnimationInstance) {
399+
val text = TextView(that)
400+
text.text = "Loop ${animation.animation.name}"
401+
events.addView(text, 0)
402+
}
214403
}
215404
}
216405

217406
animationView.registerListener(listener)
218-
219407
}
220408

409+
221410
override fun onDestroy() {
222411
super.onDestroy()
223412
animationView.destroy()
224413
}
414+
415+
225416
}
417+

app/src/main/res/raw/neostream.riv

91.6 KB
Binary file not shown.
5.12 KB
Binary file not shown.

0 commit comments

Comments
 (0)