Skip to content

Commit 3371860

Browse files
authored
Merge pull request #118 from rive-app/high-level
Adds high level constructor for Rive files over http
2 parents 3d8c092 + c19f241 commit 3371860

File tree

7 files changed

+101
-18
lines changed

7 files changed

+101
-18
lines changed

app/build.gradle

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,14 @@ android {
2929
}
3030

3131
dependencies {
32-
// Fragment dependency
33-
def fragment_version = "1.3.3"
34-
implementation "androidx.fragment:fragment-ktx:$fragment_version"
35-
3632
implementation fileTree(dir: "libs", include: ["*.jar"])
3733
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
38-
implementation 'androidx.core:core-ktx:1.3.2'
39-
implementation 'androidx.appcompat:appcompat:1.2.0'
34+
implementation 'androidx.core:core-ktx:1.5.0'
35+
implementation 'androidx.appcompat:appcompat:1.3.0'
4036
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
37+
implementation "androidx.fragment:fragment-ktx:1.3.4"
4138
implementation project(path: ':kotlin')
4239
testImplementation 'junit:junit:4.13.2'
4340
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
4441
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
45-
4642
}

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ import app.rive.runtime.kotlin.core.Rive
77

88
class SimpleActivity : AppCompatActivity() {
99

10-
private val animationView by lazy(LazyThreadSafetyMode.NONE) {
11-
findViewById<RiveAnimationView>(R.id.simple_view)
10+
private val animationViewAsset by lazy(LazyThreadSafetyMode.NONE) {
11+
findViewById<RiveAnimationView>(R.id.simple_view_asset)
12+
}
13+
14+
private val animationViewNetwork by lazy(LazyThreadSafetyMode.NONE) {
15+
findViewById<RiveAnimationView>(R.id.simple_view_network)
1216
}
1317

1418
override fun onCreate(savedInstanceState: Bundle?) {
@@ -18,6 +22,7 @@ class SimpleActivity : AppCompatActivity() {
1822

1923
override fun onDestroy() {
2024
super.onDestroy()
21-
animationView.destroy()
25+
animationViewAsset.destroy()
26+
animationViewNetwork.destroy()
2227
}
2328
}

app/src/main/res/layout/simple.xml

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,41 @@
22
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:app="http://schemas.android.com/apk/res-auto"
44
xmlns:tools="http://schemas.android.com/tools"
5+
android:id="@+id/simple_view"
56
android:layout_width="match_parent"
67
android:layout_height="match_parent"
78
tools:context=".MainActivity">
89

910
<app.rive.runtime.kotlin.RiveAnimationView
10-
android:id="@+id/simple_view"
11-
android:layout_width="match_parent"
12-
android:layout_height="match_parent"
11+
android:id="@+id/simple_view_asset"
12+
1313
app:riveResource="@raw/off_road_car_blog"
14-
/>
14+
app:riveFit="COVER"
15+
16+
android:layout_width="382dp"
17+
android:layout_height="339dp"
18+
android:layout_marginStart="16dp"
19+
android:layout_marginTop="16dp"
20+
android:layout_marginEnd="16dp"
21+
app:layout_constraintEnd_toEndOf="parent"
22+
app:layout_constraintStart_toStartOf="parent"
23+
app:layout_constraintTop_toTopOf="parent" />
24+
25+
<app.rive.runtime.kotlin.RiveAnimationView
26+
android:id="@+id/simple_view_network"
27+
28+
app:riveUrl="https://cdn.rive.app/animations/truck.riv"
29+
app:riveFit="COVER"
1530

31+
android:layout_width="381dp"
32+
android:layout_height="345dp"
33+
android:layout_marginStart="16dp"
34+
android:layout_marginTop="16dp"
35+
android:layout_marginEnd="16dp"
36+
android:layout_marginBottom="16dp"
37+
app:layout_constraintBottom_toBottomOf="parent"
38+
app:layout_constraintEnd_toEndOf="parent"
39+
app:layout_constraintStart_toStartOf="parent"
40+
app:layout_constraintTop_toBottomOf="@+id/simple_view_asset" />
1641

1742
</androidx.constraintlayout.widget.ConstraintLayout>

kotlin/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,16 @@ android {
4242
}
4343

4444
dependencies {
45+
implementation 'com.android.volley:volley:1.2.0'
4546
implementation fileTree(dir: "libs", include: ["*.jar"])
4647
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
47-
implementation 'androidx.core:core-ktx:1.3.2'
48-
implementation 'androidx.appcompat:appcompat:1.2.0'
48+
implementation 'androidx.core:core-ktx:1.5.0'
49+
implementation 'androidx.appcompat:appcompat:1.3.0'
4950
implementation 'androidx.startup:startup-runtime:1.0.0'
5051
testImplementation 'junit:junit:4.13.2'
5152
testImplementation 'androidx.test:core-ktx:1.3.0'
5253
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
5354
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
54-
5555
}
5656

5757
// Commenting this out, this only really helps when you're doing local dev, but it means our git actions need abd!

kotlin/src/main/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:tools="http://schemas.android.com/tools">
44

5+
<uses-permission android:name="android.permission.INTERNET" />
6+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
7+
58
<application>
69
<provider
710
android:name="androidx.startup.InitializationProvider"

kotlin/src/main/java/app/rive/runtime/kotlin/RiveAnimationView.kt

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,17 @@ import android.util.AttributeSet
55
import android.view.View
66
import androidx.annotation.RawRes
77
import app.rive.runtime.kotlin.core.*
8+
import com.android.volley.NetworkResponse
9+
import com.android.volley.ParseError
10+
import com.android.volley.Request
11+
import com.android.volley.Response
12+
import com.android.volley.toolbox.HttpHeaderParser
13+
import com.android.volley.toolbox.Volley
14+
import java.io.IOException
15+
import java.io.UnsupportedEncodingException
816
import java.util.*
917

18+
1019
/**
1120
* This view aims to provide the most straightforward way to get rive animations into your application.
1221
*
@@ -22,6 +31,7 @@ import java.util.*
2231
*
2332
* Xml [attrs] can be used to set initial values for many
2433
* - Provide the [resource][R.styleable.RiveAnimationView_riveResource] to load as a rive file, this can be done later with [setRiveResource] or [setRiveFile].
34+
* - Alternatively, provide the [url][R.styleable.RiveAnimationView_riveUrl] to load as a rive file over HTTP.
2535
* - Determine the [artboard][R.styleable.RiveAnimationView_riveArtboard] to use, this defaults to the first artboard in the file.
2636
* - Enable or disable [autoplay][R.styleable.RiveAnimationView_riveAutoPlay] to start the animation as soon as its available, or leave it to false to control its playback later. defaults to enabled.
2737
* - Configure [alignment][R.styleable.RiveAnimationView_riveAlignment] to specify how the animation should be aligned to its container.
@@ -111,6 +121,7 @@ class RiveAnimationView(context: Context, attrs: AttributeSet? = null) : View(co
111121
val animationName = getString(R.styleable.RiveAnimationView_riveAnimation)
112122
val stateMachineName = getString(R.styleable.RiveAnimationView_riveStateMachine)
113123
val resourceId = getResourceId(R.styleable.RiveAnimationView_riveResource, -1)
124+
val url = getString(R.styleable.RiveAnimationView_riveUrl)
114125

115126
if (resourceId != -1) {
116127
setRiveResource(
@@ -131,14 +142,36 @@ class RiveAnimationView(context: Context, attrs: AttributeSet? = null) : View(co
131142
drawable.artboardName = artboardName
132143
drawable.animationName = animationName
133144
drawable.stateMachineName = stateMachineName
134-
}
135145

146+
// If a url's been provided, initiate downloading
147+
url?.let {
148+
loadHttp(it)
149+
}
150+
}
136151
} finally {
137152
recycle()
138153
}
139154
}
140155
}
141156

157+
private fun loadHttp(url: String) {
158+
val queue = Volley.newRequestQueue(context)
159+
val stringRequest = RiveFileRequest(url,
160+
Response.Listener<File> { file ->
161+
setRiveFile(file,
162+
drawable.artboardName,
163+
drawable.animationName,
164+
drawable.stateMachineName,
165+
drawable.autoplay,
166+
drawable.fit,
167+
drawable.alignment,
168+
drawable.loop
169+
)
170+
},
171+
Response.ErrorListener { throw IOException("Unable to download Rive file $url") })
172+
queue.add(stringRequest)
173+
}
174+
142175
/**
143176
* Pauses all playing [animation instance][LinearAnimationInstance].
144177
*/
@@ -489,4 +522,24 @@ class RiveAnimationView(context: Context, attrs: AttributeSet? = null) : View(co
489522
drawable.destroy()
490523
}
491524

525+
}
526+
527+
// Custom Volley request to download and create rive files over http
528+
class RiveFileRequest(
529+
url: String,
530+
private val listener: Response.Listener<File>,
531+
errorListener: Response.ErrorListener
532+
) : Request<File>(Method.GET, url, errorListener) {
533+
534+
override fun deliverResponse(response: File) = listener.onResponse(response)
535+
536+
override fun parseNetworkResponse(response: NetworkResponse?): Response<File> {
537+
return try {
538+
val bytes = response?.data ?: ByteArray(0)
539+
val file = File(bytes)
540+
Response.success(file, HttpHeaderParser.parseCacheHeaders(response))
541+
} catch (e: UnsupportedEncodingException) {
542+
Response.error(ParseError(e))
543+
}
544+
}
492545
}

kotlin/src/main/res/values/attrs.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@
3232
<enum name="NONE" value="3"/>
3333
</attr>
3434
<attr name="riveResource" format="reference"/>
35+
<attr name="riveUrl" format="string"/>
3536
</declare-styleable>
3637
</resources>

0 commit comments

Comments
 (0)