Updated LottieSample libraries and Lottiefiles API (#1522)
Also did a bit of cleanup and converted LottiefilesFragment to epoxy-paging.
diff --git a/LottieSample/build.gradle b/LottieSample/build.gradle
index f797e29..7447eb2 100644
--- a/LottieSample/build.gradle
+++ b/LottieSample/build.gradle
@@ -12,7 +12,7 @@
applicationId "com.airbnb.lottie"
minSdkVersion 16
targetSdkVersion 29
- versionCode 67
+ versionCode 69
versionName VERSION_NAME
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -62,25 +62,29 @@
implementation project(':lottie')
implementation 'androidx.multidex:multidex:2.0.1'
- implementation "androidx.fragment:fragment:1.2.0-rc04"
- implementation("androidx.appcompat:appcompat:1.1.0")
- implementation "androidx.recyclerview:recyclerview:1.0.0"
+ implementation "androidx.fragment:fragment:1.2.1"
+ implementation "androidx.appcompat:appcompat:1.1.0"
+ implementation "androidx.recyclerview:recyclerview:1.1.0"
+ implementation "androidx.paging:paging-runtime-ktx:2.1.1"
+ implementation "androidx.paging:paging-rxjava2-ktx:2.1.1"
implementation "androidx.cardview:cardview:1.0.0"
- implementation 'androidx.core:core-ktx:1.2.0-rc01'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta1'
- implementation "androidx.browser:browser:1.0.0"
- implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0-beta01'
- kapt "androidx.lifecycle:lifecycle-common-java8:2.1.0-beta01"
- implementation "com.google.android.material:material:1.0.0"
+ implementation 'androidx.core:core-ktx:1.2.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
+ implementation "androidx.browser:browser:1.2.0"
+ implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
+ kapt "androidx.lifecycle:lifecycle-common-java8:2.2.0"
+ implementation "com.google.android.material:material:1.1.0"
- implementation 'com.airbnb.android:epoxy:2.17.0'
- kapt 'com.airbnb.android:epoxy-processor:2.17.0'
- implementation 'com.airbnb.android:mvrx:0.5.0'
+ implementation 'com.airbnb.android:epoxy:3.9.0'
+ implementation 'com.airbnb.android:epoxy-paging:3.9.0'
+ kapt 'com.airbnb.android:epoxy-processor:3.9.0'
+ implementation 'com.airbnb.android:mvrx:1.3.0'
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
- implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.0'
- implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
implementation 'com.matthew-tamlin:sliding-intro-screen:3.2.0'
implementation 'com.dlazaro66.qrcodereaderview:qrcodereaderview:2.0.2'
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.2'
diff --git a/LottieSample/src/main/assets/DynamicGradient.json b/LottieSample/src/main/assets/DynamicGradient.json
deleted file mode 100644
index 133c20c..0000000
--- a/LottieSample/src/main/assets/DynamicGradient.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.4.4","fr":30.0000305175781,"ip":0,"op":300.000305175781,"w":800,"h":400,"nm":"DyanamicGradient","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Radial","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[836,202,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[250,250],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":45,"ix":10},"g":{"p":2,"k":{"a":0,"k":[0,1,1,1,1,0,0,0],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[300,0],"ix":5},"t":2,"h":{"a":0,"k":0,"ix":6},"a":{"a":0,"k":0,"ix":7},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":13},"bm":0,"nm":"Gradient Stroke","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":2,"k":{"a":0,"k":[0,1,1,1,1,0,0,0],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[101,0],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-218,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.000305175781,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Linear","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[400,202,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[250,250],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gs","o":{"a":0,"k":100,"ix":9},"w":{"a":0,"k":45,"ix":10},"g":{"p":2,"k":{"a":0,"k":[0,1,1,1,1,0,0,0],"ix":8}},"s":{"a":0,"k":[0,0],"ix":4},"e":{"a":0,"k":[100,0],"ix":5},"t":1,"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":13},"bm":0,"nm":"Gradient Stroke","mn":"ADBE Vector Graphic - G-Stroke","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":2,"k":{"a":0,"k":[0,1,1,1,1,0,0,0],"ix":9}},"s":{"a":0,"k":[-75,0],"ix":5},"e":{"a":0,"k":[75,0],"ix":6},"t":1,"nm":"Gradient Fill","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-218,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300.000305175781,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/LottieSample/src/main/assets/LottieLogo1.json b/LottieSample/src/main/assets/Lottie Logo 1.json
similarity index 100%
rename from LottieSample/src/main/assets/LottieLogo1.json
rename to LottieSample/src/main/assets/Lottie Logo 1.json
diff --git a/LottieSample/src/main/assets/LottieLogo2.json b/LottieSample/src/main/assets/Lottie Logo 2.json
similarity index 100%
rename from LottieSample/src/main/assets/LottieLogo2.json
rename to LottieSample/src/main/assets/Lottie Logo 2.json
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/AnimationItemView.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/AnimationItemView.kt
deleted file mode 100644
index 507a98e..0000000
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/AnimationItemView.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.airbnb.lottie.samples
-
-import android.content.Context
-import android.graphics.drawable.ColorDrawable
-import android.util.AttributeSet
-import android.view.View
-import android.widget.FrameLayout
-import com.airbnb.epoxy.ModelProp
-import com.airbnb.epoxy.ModelView
-import com.airbnb.lottie.samples.model.AnimationData
-import com.airbnb.lottie.samples.model.CompositionArgs
-import kotlinx.android.synthetic.main.item_view_animation.view.*
-
-@ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT)
-class AnimationItemView @JvmOverloads constructor(
- context: Context,
- attrs: AttributeSet? = null,
- defStyleAttr: Int = 0
-) : FrameLayout(context, attrs, defStyleAttr) {
-
- private var args: CompositionArgs? = null
-
- init {
- inflate(R.layout.item_view_animation)
- }
-
- @ModelProp
- fun setAnimationData(animationData: AnimationData) {
- args = CompositionArgs(animationData = animationData)
- animationView.background = ColorDrawable(animationData.bgColorInt())
- titleView.text = animationData.title
- authorView.text = animationData.userInfo?.name ?: context.getString(R.string.anonymous)
- animationView.setImageUrl(animationData.preview)
- }
-
- @ModelProp(options = [ModelProp.Option.DoNotHash])
- fun setClickListener(listener: View.OnClickListener) {
- clickOverlay.setOnClickListener(listener)
- }
-}
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ListActivity.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ListActivity.kt
index f0bf1b8..b3fefe8 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ListActivity.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ListActivity.kt
@@ -3,6 +3,7 @@
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.airbnb.epoxy.EpoxyController
+import com.airbnb.epoxy.EpoxyRecyclerView
import com.airbnb.lottie.samples.views.WishListIconView
import com.airbnb.lottie.samples.views.listingCard
import com.airbnb.lottie.samples.views.marquee
@@ -18,7 +19,11 @@
supportActionBar?.setDisplayShowTitleEnabled(false)
toolbar.setNavigationOnClickListener { finish() }
- recyclerView.buildModelsWith { it.buildModels() }
+ recyclerView.buildModelsWith(object : EpoxyRecyclerView.ModelBuilderCallback {
+ override fun buildModels(controller: EpoxyController) {
+ controller.buildModels()
+ }
+ })
}
private fun EpoxyController.buildModels() {
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottieApplication.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottieApplication.kt
index 79379bf..451d150 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottieApplication.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottieApplication.kt
@@ -25,16 +25,18 @@
val retrofit by lazy {
Retrofit.Builder()
.client(okHttpClient)
- .baseUrl("https://lottiefiles.frb.io/api/v1/")
+ .baseUrl("https://api.lottiefiles.com/")
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
}
- val lottiefilesService by lazy { retrofit.create(LottiefilesService::class.java) }
+ val lottiefilesService by lazy { retrofit.create(LottiefilesApi::class.java) }
override fun onCreate() {
super.onCreate()
L.DBG = true
+ @Suppress("RestrictedApi")
+ L.setTraceEnabled(true)
}
}
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottiefilesApi.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottiefilesApi.kt
new file mode 100644
index 0000000..be114f6
--- /dev/null
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottiefilesApi.kt
@@ -0,0 +1,22 @@
+package com.airbnb.lottie.samples
+
+import com.airbnb.lottie.samples.model.AnimationResponse
+import com.airbnb.lottie.samples.model.AnimationResponseV2
+import io.reactivex.Single
+import retrofit2.http.GET
+import retrofit2.http.Path
+import retrofit2.http.Query
+
+interface LottiefilesApi {
+ @GET("v1/recent")
+ fun getRecent(@Query("page") page: Int): Single<AnimationResponse>
+
+ @GET("v1/popular")
+ fun getPopular(@Query("page") page: Int): Single<AnimationResponse>
+
+ @GET("v2/featured")
+ fun getCollection(): Single<AnimationResponseV2>
+
+ @GET("v1/search/{query}")
+ fun search(@Path("query") query: String, @Query("page") page: Int): Single<AnimationResponse>
+}
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottiefilesFragment.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottiefilesFragment.kt
index e66e777..763d74f 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottiefilesFragment.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottiefilesFragment.kt
@@ -1,103 +1,181 @@
package com.airbnb.lottie.samples
-import androidx.fragment.app.FragmentActivity
-import com.airbnb.epoxy.EpoxyController
+import android.os.Bundle
+import android.view.View
+import androidx.lifecycle.Observer
+import androidx.paging.DataSource
+import androidx.paging.LivePagedListBuilder
+import androidx.paging.PageKeyedDataSource
+import com.airbnb.epoxy.EpoxyModel
+import com.airbnb.epoxy.paging.PagedListEpoxyController
import com.airbnb.lottie.samples.model.AnimationData
-import com.airbnb.lottie.samples.model.AnimationResponse
import com.airbnb.lottie.samples.model.CompositionArgs
-import com.airbnb.lottie.samples.views.loadingView
+import com.airbnb.lottie.samples.views.AnimationItemViewModel_
import com.airbnb.lottie.samples.views.lottiefilesTabBar
import com.airbnb.lottie.samples.views.marquee
import com.airbnb.lottie.samples.views.searchInputItemView
-import com.airbnb.mvrx.*
-
+import com.airbnb.mvrx.BaseMvRxFragment
+import com.airbnb.mvrx.MvRxState
+import com.airbnb.mvrx.MvRxViewModelFactory
+import com.airbnb.mvrx.ViewModelContext
+import com.airbnb.mvrx.fragmentViewModel
+import com.airbnb.mvrx.withState
+import io.reactivex.schedulers.Schedulers
+import kotlinx.android.synthetic.main.fragment_epoxy_recycler_view.*
+import kotlin.properties.Delegates
data class LottiefilesState(
val mode: LottiefilesMode = LottiefilesMode.Recent,
- val items: List<AnimationData> = emptyList(),
- val request: Async<AnimationResponse> = Uninitialized,
val query: String = ""
) : MvRxState
-class LottiefilesViewModel(
- initialState: LottiefilesState,
- private val service: LottiefilesService) : MvRxViewModel<LottiefilesState>(initialState
-) {
+class LottiefilesViewModel(initialState: LottiefilesState, private val api: LottiefilesApi) : MvRxViewModel<LottiefilesState>(initialState) {
+
+ private var mode = initialState.mode
+ private var query = initialState.query
+
+ val pagedList = LivePagedListBuilder<Int, AnimationData>(object : DataSource.Factory<Int, AnimationData>() {
+ override fun create(): DataSource<Int, AnimationData> {
+ return LottiefilesDataSource(api, mode, query)
+ }
+ }, 16).build()
+
init {
- selectSubscribe(LottiefilesState::mode) { fetchMoreItems() }
+ selectSubscribe(LottiefilesState::mode, LottiefilesState::query) { mode, query ->
+ this.mode = mode
+ this.query = query
+ pagedList.value?.dataSource?.invalidate()
+ }
}
- fun fetchMoreItems() = withState { state ->
- if (state.request is Loading) return@withState
- val page = (state.request()?.currentPage ?: -1) + 1
- if (state.request()?.lastPage == page && page > 0) return@withState
+ fun setMode(mode: LottiefilesMode) = setState { copy(mode = mode) }
- when (state.mode) {
- LottiefilesMode.Recent -> service.getRecent(page)
- LottiefilesMode.Popular -> service.getPopular(page)
- LottiefilesMode.Search -> service.search(state.query)
- }.execute { copy(request = it, items = items + (it()?.data ?: emptyList())) }
- }
+ fun setQuery(query: String) = setState { copy(query = query) }
- fun setMode(mode: LottiefilesMode, query: String = "") = setState {
- if (this.mode == mode && mode != LottiefilesMode.Search) return@setState this
- if (this.mode == mode && mode == LottiefilesMode.Search && this.query == query) return@setState this
-
- copy(mode = mode, request = Uninitialized, items = emptyList(), query = query)
- }
-
- companion object : MvRxViewModelFactory<LottiefilesState> {
- @JvmStatic
- override fun create(activity: FragmentActivity, state: LottiefilesState): LottiefilesViewModel {
- val service = (activity.applicationContext as LottieApplication).lottiefilesService
+ companion object : MvRxViewModelFactory<LottiefilesViewModel, LottiefilesState> {
+ override fun create(viewModelContext: ViewModelContext, state: LottiefilesState): LottiefilesViewModel? {
+ val service = viewModelContext.app<LottieApplication>().lottiefilesService
return LottiefilesViewModel(state, service)
}
-
}
}
-class LottiefilesFragment : BaseEpoxyFragment() {
+class LottiefilesDataSource(
+ private val api: LottiefilesApi,
+ val mode: LottiefilesMode,
+ val query: String
+) : PageKeyedDataSource<Int, AnimationData>() {
+ override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, AnimationData>) {
+ if (mode == LottiefilesMode.Search && query.isEmpty()) {
+ callback.onResult(emptyList(), null, null)
+ return
+ }
+ when (mode) {
+ LottiefilesMode.Popular -> api.getPopular(1)
+ LottiefilesMode.Recent -> api.getRecent(1)
+ LottiefilesMode.Search -> api.search(query, 1)
+ }
+ .subscribeOn(Schedulers.io())
+ .subscribe(
+ { d -> callback.onResult(d.data, 0, d.total, null, 2.takeIf { d.data.isNotEmpty() }) },
+ { callback.onError(it) }
+ )
+ }
+
+ override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, AnimationData>) {
+ loadPage(params.key, callback)
+ }
+
+ override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, AnimationData>) {
+ loadPage(params.key, callback)
+ }
+
+ private fun loadPage(page: Int, callback: LoadCallback<Int, AnimationData>) {
+ when (mode) {
+ LottiefilesMode.Popular -> api.getPopular(page)
+ LottiefilesMode.Recent -> api.getRecent(page)
+ LottiefilesMode.Search -> api.search(query, page)
+ }
+ .subscribeOn(Schedulers.io())
+ .subscribe(
+ { callback.onResult(it.data, page + 1) },
+ { callback.onError(it) }
+ )
+ }
+}
+
+class LottiefilesFragment : BaseMvRxFragment(R.layout.fragment_epoxy_recycler_view) {
private val viewModel: LottiefilesViewModel by fragmentViewModel()
- override fun EpoxyController.buildModels() = withState(viewModel) { state ->
- marquee {
- id("lottiefiles")
- title(R.string.lottiefiles)
- subtitle(R.string.lottiefiles_airbnb)
- }
+ private val controller by lazy {
+ object : PagedListEpoxyController<AnimationData>() {
- lottiefilesTabBar {
- id("mode")
- mode(state.mode)
- recentClickListener { _ -> viewModel.setMode(LottiefilesMode.Recent) }
- popularClickListener { _ -> viewModel.setMode(LottiefilesMode.Popular) }
- searchClickListener { _ -> viewModel.setMode(LottiefilesMode.Search) }
- }
+ var mode by Delegates.observable(LottiefilesMode.Recent) { _, _, _ -> requestModelBuild() }
- if (state.mode == LottiefilesMode.Search) {
- searchInputItemView {
- id("search")
- searchClickListener { viewModel.setMode(LottiefilesMode.Search, it) }
- }
- }
+ override fun buildItemModel(currentPosition: Int, item: AnimationData?): EpoxyModel<*> {
+ return if (item == null) {
+ AnimationItemViewModel_().id(-currentPosition)
+ } else {
+ AnimationItemViewModel_()
+ .id(item.id)
+ .previewUrl(item.preview)
+ .title(item.title)
+ .previewBackgroundColor(item.bgColorInt)
+ .onClickListener { _ ->
+ val intent = PlayerActivity.intent(requireContext(), CompositionArgs(animationData = item))
+ requireContext().startActivity(intent)
+ }
- state.items.forEach {
- val args = CompositionArgs(animationData = it)
- animationItemView {
- id(it.id)
- animationData(it)
- clickListener { _ ->
- startActivity(PlayerActivity.intent(requireContext(), args))
}
- onBind { _, _, _ -> viewModel.fetchMoreItems() }
}
- }
- if (state.request is Loading) {
- loadingView {
- id("loading")
- onBind { _, _, _ -> viewModel.fetchMoreItems() }
+ override fun addModels(models: List<EpoxyModel<*>>) {
+ marquee {
+ id("lottiefiles")
+ title(R.string.lottiefiles)
+ subtitle(R.string.lottiefiles_airbnb)
+ }
+
+ lottiefilesTabBar {
+ id("mode")
+ mode(mode)
+ recentClickListener { _ ->
+ viewModel.setMode(LottiefilesMode.Recent)
+ requireContext().hideKeyboard()
+ }
+ popularClickListener { _ ->
+ viewModel.setMode(LottiefilesMode.Popular)
+ requireContext().hideKeyboard()
+ }
+ searchClickListener { _ ->
+ viewModel.setMode(LottiefilesMode.Search)
+ requireContext().hideKeyboard()
+ }
+ }
+
+ if (mode == LottiefilesMode.Search) {
+ searchInputItemView {
+ id("search")
+ searchClickListener(viewModel::setQuery)
+ }
+ }
+ super.addModels(models)
}
}
}
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ viewModel.pagedList.observe(this, Observer {
+ controller.submitList(it)
+ })
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ recyclerView.setController(controller)
+ }
+
+ override fun invalidate(): Unit = withState(viewModel) { state ->
+ controller.mode = state.mode
+ }
}
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottiefilesService.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottiefilesService.kt
deleted file mode 100644
index 27a9ecb..0000000
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/LottiefilesService.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.airbnb.lottie.samples
-
-import com.airbnb.lottie.samples.model.AnimationResponse
-import io.reactivex.Observable
-import retrofit2.http.GET
-import retrofit2.http.Path
-import retrofit2.http.Query
-
-interface LottiefilesService {
- @GET("recent")
- fun getRecent(@Query("page") page: Int): Observable<AnimationResponse>
-
- @GET("popular")
- fun getPopular(@Query("page") page: Int): Observable<AnimationResponse>
-
- @GET("collections/{collection}")
- fun getCollection(@Path("collection") collection: String): Observable<AnimationResponse>
-
- @GET("search/{query}")
- fun search(@Path("query") query: String): Observable<AnimationResponse>
-}
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/PlayerFragment.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/PlayerFragment.kt
index dcd63ed..632bbac 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/PlayerFragment.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/PlayerFragment.kt
@@ -12,11 +12,14 @@
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.children
+import androidx.core.view.get
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.transition.AutoTransition
import androidx.transition.TransitionManager
+import com.airbnb.epoxy.EpoxyController
+import com.airbnb.epoxy.EpoxyRecyclerView
import com.airbnb.lottie.*
import com.airbnb.lottie.model.KeyPath
import com.airbnb.lottie.samples.model.CompositionArgs
@@ -105,7 +108,7 @@
(requireActivity() as AppCompatActivity).supportActionBar?.setDisplayShowTitleEnabled(false)
setHasOptionsMenu(true)
- lottieVersionView.text = getString(R.string.lottie_version, com.airbnb.lottie.BuildConfig.VERSION_NAME)
+ lottieVersionView.text = getString(R.string.lottie_version, BuildConfig.VERSION_NAME)
animationView.setFontAssetDelegate(object : FontAssetDelegate() {
override fun fetchFont(fontFamily: String?): Typeface {
@@ -115,7 +118,13 @@
val args = arguments?.getParcelable<CompositionArgs>(EXTRA_ANIMATION_ARGS)
?: throw IllegalArgumentException("No composition args specified")
- args.animationData?.bgColorInt()?.let {
+ args.animationData?.bgColorInt?.let {
+ backgroundButton1.setBackgroundColor(it)
+ animationContainer.setBackgroundColor(it)
+ invertColor(it)
+ }
+
+ args.animationDataV2?.bgColorInt?.let {
backgroundButton1.setBackgroundColor(it)
animationContainer.setBackgroundColor(it)
invertColor(it)
@@ -438,15 +447,16 @@
// Scale up to fill the screen
scaleSeekBar.progress = 100
- keyPathsRecyclerView.buildModelsWith { controller ->
- animationView.resolveKeyPath(KeyPath("**")).forEachIndexed { index, keyPath ->
- BottomSheetItemViewModel_()
- .id(index)
- .text(keyPath.keysToString())
- .addTo(controller)
-
+ keyPathsRecyclerView.buildModelsWith(object : EpoxyRecyclerView.ModelBuilderCallback {
+ override fun buildModels(controller: EpoxyController) {
+ animationView.resolveKeyPath(KeyPath("**")).forEachIndexed { index, keyPath ->
+ BottomSheetItemViewModel_()
+ .id(index)
+ .text(keyPath.keysToString())
+ .addTo(controller)
+ }
}
- }
+ })
updateWarnings()
}
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/PlayerViewModel.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/PlayerViewModel.kt
index 7b6b6bc..dc7ad22 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/PlayerViewModel.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/PlayerViewModel.kt
@@ -3,15 +3,12 @@
import android.animation.ValueAnimator
import android.app.Application
import android.net.Uri
-import androidx.fragment.app.FragmentActivity
import com.airbnb.lottie.LottieComposition
import com.airbnb.lottie.LottieCompositionFactory
import com.airbnb.lottie.LottieTask
-import com.airbnb.lottie.model.LottieCompositionCache
import com.airbnb.lottie.samples.model.CompositionArgs
import com.airbnb.mvrx.*
import java.io.FileInputStream
-import java.io.FileNotFoundException
data class PlayerState(
val composition: Async<LottieComposition> = Uninitialized,
@@ -37,7 +34,7 @@
) : MvRxViewModel<PlayerState>(initialState) {
fun fetchAnimation(args: CompositionArgs) {
- val url = args.url ?: args.animationData?.lottieLink
+ val url = args.url ?: args.animationDataV2?.file ?: args.animationData?.lottieLink
when {
url != null -> LottieCompositionFactory.fromUrl(application, url, null)
@@ -112,8 +109,9 @@
)
}
- companion object : MvRxViewModelFactory<PlayerState> {
- @JvmStatic
- override fun create(activity: FragmentActivity, state: PlayerState) = PlayerViewModel(state, activity.application)
+ companion object : MvRxViewModelFactory<PlayerViewModel, PlayerState> {
+ override fun create(viewModelContext: ViewModelContext, state: PlayerState): PlayerViewModel? {
+ return PlayerViewModel(state, viewModelContext.app())
+ }
}
}
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ShowcaseFragment.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ShowcaseFragment.kt
index 81661b5..1fa9406 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ShowcaseFragment.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/ShowcaseFragment.kt
@@ -1,30 +1,36 @@
package com.airbnb.lottie.samples
import android.content.Intent
-import androidx.fragment.app.FragmentActivity
import com.airbnb.epoxy.EpoxyController
-import com.airbnb.lottie.samples.model.AnimationResponse
+import com.airbnb.lottie.samples.model.AnimationResponseV2
import com.airbnb.lottie.samples.model.CompositionArgs
import com.airbnb.lottie.samples.model.ShowcaseItem
+import com.airbnb.lottie.samples.views.animationItemView
import com.airbnb.lottie.samples.views.loadingView
import com.airbnb.lottie.samples.views.marquee
-import com.airbnb.lottie.samples.views.showcaseAnimationItemView
import com.airbnb.lottie.samples.views.showcaseCarousel
-import com.airbnb.mvrx.*
+import com.airbnb.mvrx.Async
+import com.airbnb.mvrx.MvRxState
+import com.airbnb.mvrx.MvRxViewModelFactory
+import com.airbnb.mvrx.Uninitialized
+import com.airbnb.mvrx.ViewModelContext
+import com.airbnb.mvrx.fragmentViewModel
+import com.airbnb.mvrx.withState
+import io.reactivex.schedulers.Schedulers
-data class ShowcaseState(val response: Async<AnimationResponse> = Uninitialized) : MvRxState
+data class ShowcaseState(val response: Async<AnimationResponseV2> = Uninitialized) : MvRxState
-class ShowcaseViewModel(initialState: ShowcaseState, service: LottiefilesService) : MvRxViewModel<ShowcaseState>(initialState) {
+class ShowcaseViewModel(initialState: ShowcaseState, api: LottiefilesApi) : MvRxViewModel<ShowcaseState>(initialState) {
init {
- service.getCollection("lottie-showcase")
+ api.getCollection()
+ .subscribeOn(Schedulers.io())
.retry(3)
.execute { copy(response = it) }
}
- companion object : MvRxViewModelFactory<ShowcaseState> {
- @JvmStatic
- override fun create(activity: FragmentActivity, state: ShowcaseState): ShowcaseViewModel {
- val service = (activity.applicationContext as LottieApplication).lottiefilesService
+ companion object : MvRxViewModelFactory<ShowcaseViewModel, ShowcaseState> {
+ override fun create(viewModelContext: ViewModelContext, state: ShowcaseState): ShowcaseViewModel? {
+ val service = viewModelContext.app<LottieApplication>().lottiefilesService
return ShowcaseViewModel(state, service)
}
}
@@ -72,11 +78,12 @@
}
} else {
collectionItems.forEach {
- showcaseAnimationItemView {
+ animationItemView {
id(it.id)
title(it.title)
- previewUrl(it.preview)
- onClickListener { _ -> startActivity(PlayerActivity.intent(requireContext(), CompositionArgs(animationData = it))) }
+ previewUrl("https://assets9.lottiefiles.com/${it.preview}")
+ previewBackgroundColor(it.bgColorInt)
+ onClickListener { _ -> startActivity(PlayerActivity.intent(requireContext(), CompositionArgs(animationDataV2 = it))) }
}
}
}
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/TypeExtensions.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/TypeExtensions.kt
index dcec895..2a72e7f 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/TypeExtensions.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/TypeExtensions.kt
@@ -4,10 +4,12 @@
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
+import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
+import android.util.Log
import androidx.annotation.DrawableRes
import androidx.annotation.LayoutRes
import androidx.annotation.StringRes
@@ -18,8 +20,13 @@
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import android.widget.TextView
+import androidx.annotation.ColorInt
+import androidx.core.content.getSystemService
+import androidx.core.graphics.toColorInt
+import com.airbnb.lottie.L
import com.bumptech.glide.Glide
fun Fragment.startActivity(cls: Class<*>) {
@@ -72,4 +79,36 @@
@Suppress("DEPRECATION")
vibrate(millis)
}
+}
+
+@ColorInt
+fun String?.toColorIntSafe(): Int {
+ var bgColor = this ?: "#ffffff"
+ bgColor = if (bgColor.startsWith("#")) bgColor else "#$bgColor"
+
+ return try {
+ when (bgColor.length) {
+ 0 -> "#ffffff"
+ 4 -> "#%c%c%c%c%c%c".format(
+ bgColor[1], bgColor[1],
+ bgColor[2], bgColor[2],
+ bgColor[3], bgColor[3]
+ )
+ 5 -> "#%c%c%c%c%c%c%c%c".format(
+ bgColor[1], bgColor[1],
+ bgColor[2], bgColor[2],
+ bgColor[3], bgColor[3],
+ bgColor[4], bgColor[4]
+ )
+ else -> bgColor
+ }.toColorInt()
+ } catch (e: IllegalArgumentException) {
+ Log.w(L.TAG, "Unable to parse $bgColor.")
+ Color.WHITE
+ }
+}
+
+fun Context.hideKeyboard() {
+ val inputMethodManager = getSystemService<InputMethodManager>()!!
+ inputMethodManager.hideSoftInputFromWindow((this as Activity).currentFocus?.windowToken, 0)
}
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/AnimationData.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/AnimationData.kt
index dfca563..c36abbb 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/AnimationData.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/AnimationData.kt
@@ -1,53 +1,18 @@
package com.airbnb.lottie.samples.model
-import android.graphics.Color
import android.os.Parcelable
-import androidx.annotation.ColorInt
-import android.util.Log
-import androidx.core.graphics.toColorInt
-import com.airbnb.lottie.L
+import com.airbnb.lottie.samples.toColorIntSafe
import kotlinx.android.parcel.Parcelize
-// This is a lint bug
-@SuppressWarnings("ParcelCreator")
@Parcelize
data class AnimationData(
val id: Long,
val title: String,
val description: String?,
private val bgColor: String?,
- val aepFile: String,
- val bodymovinVersion: String,
- val slug: String,
- val speed: String,
val preview: String?,
val lottieLink: String,
val userInfo: UserInfo?
) : Parcelable {
- @ColorInt
- fun bgColorInt(): Int {
- var bgColor = this.bgColor ?: "#ffffff"
- bgColor = if (bgColor.startsWith("#")) bgColor else "#$bgColor"
-
- return try {
- when (bgColor.length) {
- 0 -> "#ffffff"
- 4 -> "#%c%c%c%c%c%c".format(
- bgColor[1], bgColor[1],
- bgColor[2], bgColor[2],
- bgColor[3], bgColor[3]
- )
- 5 -> "#%c%c%c%c%c%c%c%c".format(
- bgColor[1], bgColor[1],
- bgColor[2], bgColor[2],
- bgColor[3], bgColor[3],
- bgColor[4], bgColor[4]
- )
- else -> bgColor
- }.toColorInt()
- } catch (e: IllegalArgumentException) {
- Log.w(L.TAG, "Unable to parse $bgColor.")
- Color.WHITE
- }
- }
+ val bgColorInt get() = bgColor.toColorIntSafe()
}
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/AnimationDataV2.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/AnimationDataV2.kt
new file mode 100644
index 0000000..7c64b4a
--- /dev/null
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/AnimationDataV2.kt
@@ -0,0 +1,40 @@
+package com.airbnb.lottie.samples.model
+
+import android.os.Parcelable
+import com.airbnb.lottie.samples.toColorIntSafe
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+data class AnimationDataV2(
+ val aepFlag: Int,
+ val baseprice: String,
+ val bgColor: String,
+ val bodymovinVersion: String?,
+ val createdAt: String,
+ val dataFile: String,
+ val description: String,
+ val downloads: Int,
+ val file: String,
+ val fileHash: String,
+ val id: Int,
+ val inProcess: Int,
+ val isSticker: Int,
+ val preview: String,
+ val previewFrame: Int,
+ val previewUrl: String,
+ val previewVideo: String,
+ val previewVideoUrl: String,
+ val price: Int,
+ val publishedAt: String,
+ val slug: String,
+ val speed: Int,
+ val status: Int,
+ val title: String,
+ val updated_at: String,
+ val userId: Int,
+ val videoFramerate: Int,
+ val views: Int
+) : Parcelable {
+ val bgColorInt get() = bgColor.toColorIntSafe()
+
+}
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/AnimationResponseV2.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/AnimationResponseV2.kt
new file mode 100644
index 0000000..9a4a159
--- /dev/null
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/AnimationResponseV2.kt
@@ -0,0 +1,16 @@
+package com.airbnb.lottie.samples.model
+
+data class AnimationResponseV2(
+ val current_page: Int,
+ val data: List<AnimationDataV2>,
+ val first_page_url: String,
+ val from: Int,
+ val last_page: Int,
+ val last_page_url: String,
+ val next_page_url: Any,
+ val path: String,
+ val per_page: Int,
+ val prev_page_url: Any,
+ val to: Int,
+ val total: Int
+)
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/CompositionArgs.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/CompositionArgs.kt
index 0e0fdf8..8192d95 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/CompositionArgs.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/model/CompositionArgs.kt
@@ -12,5 +12,6 @@
val url: String? = null,
val fileUri: Uri? = null,
val asset: String? = null,
- val animationData: AnimationData? = null
+ val animationData: AnimationData? = null,
+ val animationDataV2: AnimationDataV2? = null
) : Parcelable
\ No newline at end of file
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/ShowcaseAnimationItemView.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/AnimationItemView.kt
similarity index 70%
rename from LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/ShowcaseAnimationItemView.kt
rename to LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/AnimationItemView.kt
index 168c9e7..e94c588 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/ShowcaseAnimationItemView.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/AnimationItemView.kt
@@ -3,6 +3,7 @@
import android.content.Context
import android.util.AttributeSet
import android.widget.FrameLayout
+import androidx.annotation.ColorInt
import com.airbnb.epoxy.ModelProp
import com.airbnb.epoxy.ModelView
import com.airbnb.epoxy.TextProp
@@ -12,7 +13,7 @@
import kotlinx.android.synthetic.main.item_view_showcase_animation.view.*
@ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT)
-class ShowcaseAnimationItemView @JvmOverloads constructor(
+class AnimationItemView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
@@ -28,10 +29,20 @@
}
@TextProp
- fun setTitle(title: CharSequence) {
+ fun setTitle(title: CharSequence?) {
titleView.text = title
}
+ @ModelProp
+ fun setPreviewBackgroundColor(@ColorInt bgColor: Int?) {
+ if (bgColor == null) {
+ imageView.setBackgroundResource(R.color.loading_placeholder)
+ imageView.setImageDrawable(null)
+ } else {
+ imageView.setBackgroundColor(bgColor)
+ }
+ }
+
@ModelProp(options = [ModelProp.Option.DoNotHash])
override fun setOnClickListener(l: OnClickListener?) {
container.setOnClickListener(l)
diff --git a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/SearchInputItemView.kt b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/SearchInputItemView.kt
index 318d4d0..0037c64 100644
--- a/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/SearchInputItemView.kt
+++ b/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/views/SearchInputItemView.kt
@@ -6,6 +6,7 @@
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.FrameLayout
+import androidx.core.content.getSystemService
import com.airbnb.epoxy.ModelProp
import com.airbnb.epoxy.ModelView
import com.airbnb.lottie.samples.R
@@ -36,8 +37,8 @@
@ModelProp(options = [ModelProp.Option.DoNotHash])
fun setSearchClickListener(listener: (String) -> Unit) {
searchButton.setOnClickListener {
- val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
- inputMethodManager.hideSoftInputFromInputMethod(windowToken, 0)
+ val inputMethodManager = context.getSystemService<InputMethodManager>()!!
+ inputMethodManager.hideSoftInputFromWindow(windowToken, 0)
listener(searchEditText.text.toString())
}
}
diff --git a/LottieSample/src/main/res/layout/fragment_base.xml b/LottieSample/src/main/res/layout/fragment_base.xml
index bd6a661..4c25116 100644
--- a/LottieSample/src/main/res/layout/fragment_base.xml
+++ b/LottieSample/src/main/res/layout/fragment_base.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/coordinatorLayout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:id="@+id/coordinatorLayout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
<com.airbnb.epoxy.EpoxyRecyclerView
android:id="@+id/recyclerView"
diff --git a/LottieSample/src/main/res/layout/item_view_animation.xml b/LottieSample/src/main/res/layout/item_view_animation.xml
deleted file mode 100644
index 9231cb0..0000000
--- a/LottieSample/src/main/res/layout/item_view_animation.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="24dp"
- android:layout_marginRight="24dp">
-
- <ImageView
- android:id="@+id/animationView"
- android:layout_width="match_parent"
- android:background="@drawable/list_item_animation_background"
- app:layout_constraintBottom_toTopOf="@id/titleView"
- app:layout_constraintDimensionRatio="1"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
- <TextView
- android:id="@+id/titleView"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginEnd="8dp"
- android:layout_marginRight="8dp"
- android:layout_marginTop="8dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/animationView"
- tools:text="Loading Animation 1" />
-
- <TextView
- android:id="@+id/authorView"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginBottom="24dp"
- android:layout_marginEnd="8dp"
- android:layout_marginRight="8dp"
- android:layout_marginTop="8dp"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="@+id/titleView"
- app:layout_constraintTop_toBottomOf="@+id/titleView"
- tools:text="Gabriel Peal" />
-
- <View
- android:id="@+id/clickOverlay"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:background="?attr/selectableItemBackground"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="@+id/animationView" />
-
-
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/LottieSample/src/main/res/layout/item_view_search_input.xml b/LottieSample/src/main/res/layout/item_view_search_input.xml
index d247673..e731a42 100644
--- a/LottieSample/src/main/res/layout/item_view_search_input.xml
+++ b/LottieSample/src/main/res/layout/item_view_search_input.xml
@@ -7,8 +7,8 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginLeft="24dp"
- android:layout_marginRight="24dp"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
android:orientation="horizontal">
<EditText
diff --git a/LottieSample/src/main/res/layout/list_item_preview.xml b/LottieSample/src/main/res/layout/list_item_preview.xml
index e44c95a..59fb1b6 100644
--- a/LottieSample/src/main/res/layout/list_item_preview.xml
+++ b/LottieSample/src/main/res/layout/list_item_preview.xml
@@ -8,8 +8,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="18dp"
- android:paddingLeft="24dp"
- android:paddingRight="24dp"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
android:paddingTop="18dp"
android:gravity="center_vertical"
android:orientation="horizontal"
diff --git a/LottieSample/src/main/res/layout/lottiefiles_tab_bar.xml b/LottieSample/src/main/res/layout/lottiefiles_tab_bar.xml
index 74f74b8..bfa86ac 100644
--- a/LottieSample/src/main/res/layout/lottiefiles_tab_bar.xml
+++ b/LottieSample/src/main/res/layout/lottiefiles_tab_bar.xml
@@ -8,7 +8,7 @@
android:id="@+id/recentView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginLeft="24dp"
+ android:layout_marginLeft="16dp"
android:layout_marginRight="24dp"
android:background="?attr/selectableItemBackground"
app:titleText="@string/recent"/>
diff --git a/LottieSample/src/main/res/layout/marquee.xml b/LottieSample/src/main/res/layout/marquee.xml
index e6a2e97..125c0eb 100644
--- a/LottieSample/src/main/res/layout/marquee.xml
+++ b/LottieSample/src/main/res/layout/marquee.xml
@@ -9,8 +9,8 @@
android:id="@+id/titleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginLeft="24dp"
- android:layout_marginTop="64dp"
+ android:layout_marginLeft="16dp"
+ android:layout_marginTop="24dp"
android:textSize="32sp"
android:textStyle="bold"
android:textColor="@color/text_color_dark"/>
@@ -19,7 +19,7 @@
android:id="@+id/subtitleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginLeft="24dp"
+ android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:textSize="16sp"
android:textStyle="bold"
diff --git a/build.gradle b/build.gradle
index 38fcd03..b9600ba 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
import org.ajoberstar.grgit.Grgit
buildscript {
- ext.kotlinVersion = '1.3.41'
+ ext.kotlinVersion = '1.3.61'
repositories {
jcenter()