- 投稿日:2021-03-03T23:15:43+09:00
error Runner.app/Info.plist does not exist. The Flutter "Thin Binary" build phase must run after "Copy Bundle Resources".が出たら
ここを参考にした
ちなみに自分はAndroid StudioでClean Build Folderだけでなおった
- 投稿日:2021-03-03T16:59:15+09:00
Android Studio 電卓アプリ制作
出来るだけコードが少なくなるように電卓アプリを作成しました。
改善点などご教授いただけますと幸いです。
YouTubeに作っている動画をアップしています。
https://www.youtube.com/watch?v=kvz7gLP3SHI&list=PLhg2PHSq8bjisIZGg-cLe4TegqJTCBXhSstrings.xml<resources> <string name="app_name">CalculateApp</string> <string name="btn_zero">0</string> <string name="btn_one">1</string> <string name="btn_two">2</string> <string name="btn_three">3</string> <string name="btn_four">4</string> <string name="btn_five">5</string> <string name="btn_six">6</string> <string name="btn_seven">7</string> <string name="btn_eight">8</string> <string name="btn_nine">9</string> <string name="btn_plus">+</string> <string name="btn_minus">-</string> <string name="btn_times">×</string> <string name="btn_divide">÷</string> <string name="btn_clear">C</string> <string name="btn_point">.</string> <string name="btn_equal">=</string> </resources>activity_main.xml<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:weightSum="7" tools:context=".MainActivity"> <TextView android:id="@+id/text_formula" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="right" android:textSize="36sp"></TextView> <TextView android:id="@+id/text_result" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="right" android:textSize="36sp" android:textStyle="bold"></TextView> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:weightSum="4"> <Space android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1"></Space> <Space android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1"></Space> <Space android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1"></Space> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_clear" android:onClick="tapClear" android:textSize="36sp"></Button> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:weightSum="4"> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_seven" android:onClick="tapSeven" android:textSize="36sp"></Button> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_eight" android:onClick="tapEight" android:textSize="36sp"></Button> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_nine" android:onClick="tapNine" android:textSize="36sp"></Button> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_divide" android:onClick="tapDivide" android:textSize="36sp"></Button> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:weightSum="4"> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_four" android:onClick="tapFour" android:textSize="36sp"></Button> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_five" android:onClick="tapFive" android:textSize="36sp"></Button> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_six" android:onClick="tapSix" android:textSize="36sp"></Button> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_times" android:onClick="tapTimes" android:textSize="36sp"></Button> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:weightSum="4"> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_one" android:onClick="tapOne" android:textSize="36sp"></Button> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_two" android:onClick="tapTwo" android:textSize="36sp"></Button> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_three" android:onClick="tapThree" android:textSize="36sp"></Button> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_minus" android:onClick="tapMinus" android:textSize="36sp"></Button> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal" android:weightSum="4"> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_zero" android:onClick="tapZero" android:textSize="36sp"></Button> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_point" android:onClick="tapPoint" android:textSize="36sp"></Button> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_equal" android:onClick="tapEqual" android:textSize="36sp"></Button> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_margin="2dp" android:layout_weight="1" android:text="@string/btn_plus" android:onClick="tapPlus" android:textSize="36sp"></Button> </LinearLayout> </LinearLayout>MainActivity.javapackage com.example.calculateapp; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.TextView; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class MainActivity extends AppCompatActivity { TextView formula, result; List<String> symbols; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); formula = findViewById(R.id.text_formula); result = findViewById(R.id.text_result); symbols = new ArrayList<String>(); } public void tapZero(View view) { formula.setText(formula.getText().toString() + "0"); } public void tapOne(View view) { formula.setText(formula.getText().toString() + "1"); } public void tapTwo(View view) { formula.setText(formula.getText().toString() + "2"); } public void tapThree(View view) { formula.setText(formula.getText().toString() + "3"); } public void tapFour(View view) { formula.setText(formula.getText().toString() + "4"); } public void tapFive(View view) { formula.setText(formula.getText().toString() + "5"); } public void tapSix(View view) { formula.setText(formula.getText().toString() + "6"); } public void tapSeven(View view) { formula.setText(formula.getText().toString() + "7"); } public void tapEight(View view) { formula.setText(formula.getText().toString() + "8"); } public void tapNine(View view) { formula.setText(formula.getText().toString() + "9"); } public void tapPoint(View view) { formula.setText(formula.getText().toString() + "."); } public void tapPlus(View view) { formula.setText(formula.getText().toString() + "+"); symbols.add("+"); } public void tapMinus(View view) { formula.setText(formula.getText().toString() + "-"); symbols.add("-"); } public void tapTimes(View view) { formula.setText(formula.getText().toString() + "×"); symbols.add("×"); } public void tapDivide(View view) { formula.setText(formula.getText().toString() + "÷"); symbols.add("÷"); } public void tapClear(View view) { formula.setText(""); result.setText(""); symbols.clear(); } public void tapEqual(View view) { BigDecimal tmp; BigDecimal numResult = new BigDecimal(0); String TextFormula = formula.getText().toString(); List<String> nums = Arrays.asList(TextFormula.split("[\\+\\-×÷]", -1)); List<BigDecimal> numbers = new ArrayList<BigDecimal>(); try { if ((nums.get(0).length() == 0) && (symbols.get(0) == "-")) { nums.set(0, "0"); } for (String num : nums){ numbers.add(new BigDecimal(num)); } for (int i = 0; i < symbols.size(); i++) { switch (symbols.get(i)) { case "×": tmp = numbers.get(i).multiply(numbers.get(i+1)); numbers.set(i,new BigDecimal(0)); numbers.set(i + 1, tmp); break; case "÷": tmp = numbers.get(i).divide(numbers.get(i+1),2,BigDecimal.ROUND_HALF_UP); numbers.set(i,new BigDecimal(0)); numbers.set(i + 1, tmp); break; case "-": numbers.set(i+1,numbers.get(i+1).multiply(new BigDecimal(-1))); break; } } for (BigDecimal num : numbers) { numResult = numResult.add(num); } result.setText(numResult.toString()); } catch (Exception e) { Log.e("エラー", e.getMessage()); } } }縦画面に固定したいので、マニフェストに追記
AndroidManifest.xml<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.calculateapp"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.CalculateApp"> <activity android:name=".MainActivity" android:screenOrientation="portrait">//縦画面固定 <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>YouTubeに作っている動画をアップしています。
https://www.youtube.com/watch?v=kvz7gLP3SHI&list=PLhg2PHSq8bjisIZGg-cLe4TegqJTCBXhS
以上。
- 投稿日:2021-03-03T14:55:07+09:00
Android StudioでリリースAPK(署名付き)を作成してみた。
Android StudioでリリースAPK(署名付き)を作成してみた。
最初に
Build Variantをrelease設定してBuild APK(s)を実行して署名付きリリースAPKを作成する時の手順の記事となります。
また今回の記事はリリースAPKを作成して端末にインストールしてみたので自分の覚書用に
作成した物なので、参考になるかどうかは保証しかねるのでご了承の上お読みください。
*画面スクショは気が向いたら後日追加するかも?1.KeyStoreを作成
Build -> Generate Signed Bundle or apk をクリック
*もしかしたら...で省略されてるかも
↓
開いたウィンドウでapk を選んで次へ
↓
「key store path」の編集ボックスの下のボタンをクリック(Create New ...)
↓
keyStoreの作成画面が開くので以下の項目を入力してOKをクリック
・Key Store path :KeyStoreの保存場所(path/xxx.jks)
*pathだけでなくkeyStore名もここで記述する必要あり
*gradleにstorePasswordの変数名?で記述する
・Password :キーストアのパスワード。署名設定時に必要。6文字以上必要。
・Alias : キーを識別する任意の名前。
*gradleにkeyAliasの変数名?で記述する
・PassWord(key) : キーのパスワード。
*gradleにkeyPasswordの変数名?で記述する
・Validity(Yeas) : 有効年数
・Certificate :証明書の所有者に関する情報。どれか一つに入力が必要。今回は「First and ...」に入力した
*他にも入力項目はあるが上記の物を入力したらとりあえずは作成できた
↓
とりあえずエラーが出るが、無視して入力したpathにkeyStoreが作成されている事が確認できたら
ウィンドウを閉じてしまってOK(APKはgradle設定後にBuild Apkで作成するから)2.Build.gradle(app)に追記
android{ (略) ・ ・ signingConfigs { release { storeFile file(“xxx/xxx.jks”) // KeyStore作成時に設定した値を覚えておく必要有り storePassword ‘XXXXX’ keyAlias ‘XXXX’ keyPassword ‘XXXX’ } } buildTypes { release { (略) ・ ・ signingConfig signingConfigs.release } } // 署名付きAPKを作ろうとするとLintエラーが出るのでその対策 lintOptions { checkReleaseBuilds false abortOnError false } }上記の物を追加したらSyncを実行する
3.署名付きリリースAPKを作成
Build Variant を releaseに設定
Build-> Build Bundle(s)/APK(s)->Build APK(s)をクリックして
署名付きリリースAPKを作成
作成が終了したらAndroid studioの何処かにBuild APK(s)の通知が出る。
成功時にはlocate(ハイパーリンク)が通知の中にあるのでそれをクリックするとAPKが作られたディレクトリが開く。
参考・引用元
Qita記事
・Android studioにおけるbuild.gradleの設定について
・Android Studioで署名付きAPK作成時にLintエラーが出た場合の対処法
外部サイト
・なんちゃって情シス/【Android Studio】Key store pathを初めて作成する
- 投稿日:2021-03-03T13:06:52+09:00
Azure PipelinesのYAMLでAndroidアプリのCI環境を構築する方法
「Azure PipelinesのYAMLでAndroidアプリのCI/CD環境を構築する」は3部構成です。
記事を順番に読み進めると、Azure PipelinesでAndroidアプリのCI/CD環境が構築できるようになります。
- 第一部:CI環境の構築 ←イマココ
- 第二部:App Center配布パイプラインの構築(未投稿)
- 第三部:Google Play Console配布パイプラインの構築(未投稿)
はじめに
Azure Pipelinesを使い、Androidアプリのビルドと単体テスト、静的解析を行うCIを構築します。
本記事で説明しないこと
- Azure Pipelinesの概要や基本的な操作方法
私が以前書いた記事 が参考になると思います設定ファイルの構成
Azure PipelinesのYAMLでiOSアプリのCI環境を構築する方法 と同様なので省略します。
各項目の紹介
各項目を上から順に紹介します。
trigger
Azure PipelinesのYAMLでiOSアプリのCI環境を構築する方法 と同様なので説明は省略します。
設定のみ紹介します。
trigger: batch: true branches: include: - main - develop paths: exclude: - docs - README.md - LICENSEschedules
Azure PipelinesのYAMLでiOSアプリのCI環境を構築する方法 と同様なので省略します。
設定のみ紹介します。
schedules: - cron: "0 15 * * *" displayName: Daily midnight build branches: include: - main - develop always: truevariables
今回は使っていないので省略します。
jobs
今回はジョブを3つ用意しており、順番に紹介します。
test
ビルドと単体テストを実行するジョブです。
GitHub ActionsでAndroidアプリのCIを構築する方法 とほぼ同様なので、全体図のみ紹介します。
ちなみにビルドタイプとプロダクトフレーバーは以下の想定です。
環境によって読み替えてください。
- ビルドタイプ:
debug
- プロダクトフレーバー:
production
jobs: - job: test pool: vmImage: 'ubuntu-latest' steps: # JDKのセットアップ - task: JavaToolInstaller@0 inputs: versionSpec: '8' jdkArchitectureOption: 'x64' jdkSourceOption: 'PreInstalled' # 依存関係の出力 - script: ./gradlew androidDependencies displayName: Displays the Android dependencies of the project # コンパイル - script: ./gradlew assembleDebug displayName: Run Compile # テスト - script: ./gradlew testProductionDebugUnitTest displayName: Test with Gradle # アーティファクトのステージングへコピー - task: CopyFiles@2 inputs: Contents: | **/build/reports/tests/**/* **/build/reports/test-results/**/* TargetFolder: '$(Build.ArtifactStagingDirectory)' condition: succeededOrFailed() # アーティファクトへアップロード - task: PublishBuildArtifacts@1 inputs: pathtoPublish: '$(Build.ArtifactStagingDirectory)' artifactName: 'drop' publishLocation: 'Container' condition: succeededOrFailed() # コードカバレッジの取得 - script: ./gradlew jacocoProductionDebugTestReport displayName: Get code coverage # コードカバレッジのアップロード - task: PublishCodeCoverageResults@1 inputs: codeCoverageTool: 'jacoco' summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/build/reports/jacoco/jacoco.xml' reportDirectory: '$(System.DefaultWorkingDirectory)/**/build/reports/jacoco/html' failIfCoverageEmpty: trueコードカバレッジの確認
「コードカバレッジのアップロード」タスクに成功すると、CIの結果に[Code Coverage]タブが追加され、コードカバレッジを確認できます。
画像が表示されないのはセキュリティの理由だそうです。
Base64変換すれば表示できるとのことですが、そこまではやっていません。
reportDirectory:
を指定しないとCIの結果からコードカバレッジを確認できないので注意です。
注意
- 「JDKのセットアップ」タスクが必要かわからない
jacocoProductionDebugTestReport
タスクは自作
- 別記事で説明する予定
- テスト結果は成否にかかわらず確認したいため、アーティファクトのアップロードタスクで
condition: succeededOrFailed()
を指定している
- 「アーティファクトへアップロード」タスクは「アーティファクトのステージングへコピー」タスクが成功した場合のみ実行したいが、かんたんには実現できなさそう
参考: https://twitter.com/the_uhooi/status/1366216298540146693?s=20lint
Android Lintを使って静的解析するジョブです。
GitHub ActionsでAndroidアプリのCIを構築する方法 とほぼ同様なので、全体図のみ紹介します。
- job: lint pool: vmImage: 'ubuntu-latest' steps: # 静的解析 - script: ./gradlew lint displayName: Run Inspection # アーティファクトのステージングへコピー - task: CopyFiles@2 inputs: Contents: | **/build/reports/lint-results.html **/build/reports/lint-results.xml TargetFolder: '$(Build.ArtifactStagingDirectory)' condition: succeededOrFailed() # アーティファクトへアップロード - task: PublishBuildArtifacts@1 inputs: pathtoPublish: '$(Build.ArtifactStagingDirectory)' artifactName: 'drop' publishLocation: 'Container' condition: succeededOrFailed()Android Lintの結果は静的解析の成否にかかわらず確認したいため、アーティファクトのアップロードタスクで
condition: succeededOrFailed()
を指定しています。detekt
detektを使って静的解析するジョブです。
GitHub ActionsでAndroidアプリのCIを構築する方法 とほぼ同様なので、全体図のみ紹介します。
- job: detekt pool: vmImage: 'ubuntu-latest' steps: # 静的解析 - script: ./gradlew detekt displayName: Lint with detekt # アーティファクトのステージングへコピー - task: CopyFiles@2 inputs: Contents: | **/build/reports/detekt/**/* TargetFolder: '$(Build.ArtifactStagingDirectory)' condition: failed() # アーティファクトへアップロード - task: PublishBuildArtifacts@1 inputs: pathtoPublish: '$(Build.ArtifactStagingDirectory)' artifactName: 'drop' publishLocation: 'Container' condition: failed()失敗時のみ結果を詳細に確認したいため、アーティファクトのアップロードタスクで
condition: failed()
を指定しています。設定ファイルの全体図
最後に設定ファイルの全体図を載せます。
trigger: batch: true branches: include: - main - develop paths: exclude: - docs - README.md - LICENSE schedules: - cron: "0 15 * * *" displayName: Daily midnight build branches: include: - main - develop always: true jobs: - job: test pool: vmImage: 'ubuntu-latest' steps: # JDKのセットアップ - task: JavaToolInstaller@0 inputs: versionSpec: '8' jdkArchitectureOption: 'x64' jdkSourceOption: 'PreInstalled' # 依存関係の出力 - script: ./gradlew androidDependencies displayName: Displays the Android dependencies of the project # コンパイル - script: ./gradlew assembleDebug displayName: Run Compile # テスト - script: ./gradlew testProductionDebugUnitTest displayName: Test with Gradle # アーティファクトのステージングへコピー - task: CopyFiles@2 inputs: Contents: | **/build/reports/tests/**/* **/build/reports/test-results/**/* TargetFolder: '$(Build.ArtifactStagingDirectory)' condition: succeededOrFailed() # アーティファクトへアップロード - task: PublishBuildArtifacts@1 inputs: pathtoPublish: '$(Build.ArtifactStagingDirectory)' artifactName: 'drop' publishLocation: 'Container' condition: succeededOrFailed() # コードカバレッジの取得 - script: ./gradlew jacocoProductionDebugTestReport displayName: Get code coverage # コードカバレッジのアップロード - task: PublishCodeCoverageResults@1 inputs: codeCoverageTool: 'jacoco' summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/build/reports/jacoco/jacoco.xml' reportDirectory: '$(System.DefaultWorkingDirectory)/**/build/reports/jacoco/html' failIfCoverageEmpty: true - job: lint pool: vmImage: 'ubuntu-latest' steps: # 静的解析 - script: ./gradlew lint displayName: Run Inspection # アーティファクトのステージングへコピー - task: CopyFiles@2 inputs: Contents: | **/build/reports/lint-results.html **/build/reports/lint-results.xml TargetFolder: '$(Build.ArtifactStagingDirectory)' condition: succeededOrFailed() # アーティファクトへアップロード - task: PublishBuildArtifacts@1 inputs: pathtoPublish: '$(Build.ArtifactStagingDirectory)' artifactName: 'drop' publishLocation: 'Container' condition: succeededOrFailed() - job: detekt pool: vmImage: 'ubuntu-latest' steps: # 静的解析 - script: ./gradlew detekt displayName: Lint with detekt # アーティファクトのステージングへコピー - task: CopyFiles@2 inputs: Contents: | **/build/reports/detekt/**/* TargetFolder: '$(Build.ArtifactStagingDirectory)' condition: failed() # アーティファクトへアップロード - task: PublishBuildArtifacts@1 inputs: pathtoPublish: '$(Build.ArtifactStagingDirectory)' artifactName: 'drop' publishLocation: 'Container' condition: failed()シンプルなYAMLファイルなので、慣れれば読みやすいと思います。
おまけ: PR時にCIを回す
Azure PipelinesのYAMLでiOSアプリのCI環境を構築する方法 と同様なので省略します。
他にやりたいこと
実現できていないことを備忘録として残します。
- キャッシュの取得
- [Test]タブの追加
- [Code Coverage]タブで画像の表示
おわりに
Azure PipelinesのYAMLで基本的なAndroidアプリのCIを回すことができました!
キャッシュが取れていなかったりと改善点もありますが、参考になれば幸いです。
参考リンク
- Expressions - Azure Pipelines | Microsoft Docs
- Conditions - Azure Pipelines | Microsoft Docs
- Java Tool Installer task - Azure Pipelines | Microsoft Docs
- Publish Code Coverage Results task - Azure Pipelines | Microsoft Docs
- コマンドラインからのテスト | Android デベロッパー | Android Developers
- lint チェックでコードを改善する | Android デベロッパー | Android Developers
- Continue Azure Pipeline on failed task - Stack Overflow
- 投稿日:2021-03-03T11:46:52+09:00
LottieをリソースIDでデータバインディングしてコードをスッキリ
Lottieは簡単に素敵なアニメーションを追加できるAirbnbのライブラリです。
更に使いやすくresourceIdでデータバインディングできるようにカスタムBindingAdapterを用意して使ってみました。カスタムBindingAdapterを作成
LottieAnimationViewBindingAdapter.javaimport androidx.annotation.RawRes; import androidx.databinding.BindingAdapter; import androidx.databinding.BindingMethod; import androidx.databinding.BindingMethods; import com.airbnb.lottie.LottieAnimationView; @BindingMethods({ @BindingMethod(type = com.airbnb.lottie.LottieAnimationView.class, attribute = "lottie_rawRes", method = "setAnimation"), }) public class LottieAnimationViewBindingAdapter { @BindingAdapter("lottie_rawRes") public static void setAnimation(LottieAnimationView view, @RawRes final int rawRes) { view.setAnimation(rawRes); view.playAnimation(); } }ViewModelでResId用のLiveDataを作成
HogeViewModel.ktval animationResId: LiveData<Int> = Transformations.map(hoge) { when { hoge.value!! > THRESHOLD -> R.raw.rocket_in_space else -> R.raw.lighthouse } }レイアウトにバインド
hoge_fragment.xml<data> <variable name="vm" type="com.hoge.HogeViewModel" /> </data> ... <com.airbnb.lottie.LottieAnimationView android:id="@+id/animationView" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintBottom_toTopOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:lottie_autoPlay="true" app:lottie_loop="true" app:lottie_rawRes="@{vm.animationResId}" />