色欲香天天综合网站,亚洲AV优女天堂熟女,色一情一乱一伦一区二区三欧美,日本久久综合久久综合

Android車載HMI—Lottie講解

1.前言 多年以前汽車還是以機(jī)械儀表主體的年代,各大汽車主機(jī)廠商并不十分關(guān)注操作系統(tǒng)UI的交互功能,但是隨著車載SOC算力的不斷提高以及主機(jī)廠商對(duì)汽車座艙競(jìng)爭(zhēng)的白熱化。座艙的HMI在設(shè)計(jì)上在強(qiáng)調(diào)功能...

1.前言

多年以前汽車還是以機(jī)械儀表主體的年代,各大汽車主機(jī)廠商并不十分關(guān)注操作系統(tǒng)UI的交互功能,但是隨著車載SOC算力的不斷提高以及主機(jī)廠商對(duì)汽車座艙競(jìng)爭(zhēng)的白熱化。座艙的HMI在設(shè)計(jì)上在強(qiáng)調(diào)功能性的同時(shí)也開始關(guān)注UI的藝術(shù)性,HMI的設(shè)計(jì)師們期望藝術(shù)與功能應(yīng)該協(xié)同工作,讓用戶沉浸在“第三空間”的體驗(yàn)中。

有了需求程序員就需要關(guān)注如何實(shí)施和落地,然而Android應(yīng)用本身雖然有著完整的動(dòng)畫框架支持,但是開發(fā)復(fù)雜、調(diào)試耗時(shí),大型的gif或逐幀動(dòng)畫對(duì)于CPU&內(nèi)存占用都不太理想,所以許多Android的手機(jī)應(yīng)用基本上不怎么有動(dòng)畫。而且車載HMI上越來越多的開始引入各種光影、粒子效果,如果基于Android的原生控件來實(shí)現(xiàn)這些粒子效果,難度非常大,這就需要今天的主角Lottie來實(shí)現(xiàn)了。

Android車載HMI—Lottie講解插圖

2.Lottie概述

Lottie是一種基于JSON的動(dòng)畫文件格式,它使設(shè)計(jì)師能夠在任何平臺(tái)上發(fā)布動(dòng)畫,就像發(fā)布靜態(tài)資產(chǎn)一樣簡(jiǎn)單。它們是在任何設(shè)備上工作的小文件,可以在不進(jìn)行像素化的情況下放大或縮小。

GitHub:https://github.com/airbnb/lottie-android 官方文檔:http://airbnb.io/lottie/

Lottie在車載HMI中的優(yōu)勢(shì)

適量圖形,不會(huì)出現(xiàn)失真

占用空間比序列幀動(dòng)畫小

可以修改屬性,動(dòng)態(tài)生成可交互的動(dòng)畫(使用視頻動(dòng)畫難以實(shí)現(xiàn)交互功能)

節(jié)省HMI的開發(fā)、調(diào)試時(shí)間

可以更輕松的實(shí)現(xiàn)粒子、光影等特效

Lottie的使用方法

在build.gradle中添加依賴
dependencies { def lottieVersion = “5.2.0” implementation com.airbnb.android:lottie:$lottieVersion }
使用LottieAnimationView 首先將lottie動(dòng)畫的json文件放在assets文件夾下
Android車載HMI—Lottie講解插圖1
img

然后就可以在布局文件中使用LottieAnimationView了

<com.airbnb.lottie.LottieAnimationView android:id=”@+id/dynamic_text” android:layout_width=”wrap_content” android:layout_height=”wrap_content” app:lottie_fileName=”HamburgerArrow.json” app:lottie_autoPlay=”true” app:lottie_loop=”true”/>

然后運(yùn)行APP就可以看到動(dòng)畫效果

Android車載HMI—Lottie講解插圖2

3.Lottie的常用屬性&API

LottieAnimationView繼承自AppCompatImageView,所以ImageView支持的屬性,LottieAnimationView都是支持的,這部分就不再介紹了。

lottie_fileName 設(shè)定lottie動(dòng)畫所對(duì)應(yīng)的json文件地址。json文件默認(rèn)需要放置在assets下,設(shè)定時(shí)不需要再?gòu)?qiáng)調(diào)assets
app:lottie_fileName=“HamburgerArrow.json”

如果設(shè)定 app:lottie_fileName=”other/HamburgerArrow.json”,那么lottie就會(huì)讀取assets/other/HamburgerArrow.json。 void setAnimationFromJson(String jsonString, @Nullable String cacheKey)

lottie_rawRes 設(shè)定lottie動(dòng)畫的json文件地址。json文件除了可以放置assets文件夾下,還可以放在raw文件夾下。使用時(shí)需要注意,利用lottie_rawRes引入資源時(shí),json文件名前需要加上@raw,并且文件名不帶.json后綴
app:lottie_rawRes=“@raw/name”
Android車載HMI—Lottie講解插圖3

imglottie_autoPlay 設(shè)定是否自動(dòng)播放,取值為true | false

lottie_loop 設(shè)定是否循環(huán)播放,取值為true | false

lottie_url 當(dāng)需要加載在線資源時(shí),就可以使用lottie_url void setAnimationFromUrl(String url) void setAnimationFromUrl(String url, @Nullable String cacheKey)

lottie_fallbackRes 設(shè)置一個(gè)drawable,如果lotticomposition由于任何原因未能加載,則將呈現(xiàn)該drawable。 如果這是網(wǎng)絡(luò)動(dòng)畫,可以使用它向用戶顯示錯(cuò)誤,也可以添加一個(gè)失敗的監(jiān)聽器重試下載。 void setFallbackResource(@DrawableRes int fallbackResource)

lottie_repeatMode 設(shè)定循環(huán)播放的順序。取值為restart | reverse 。restart表示正常循環(huán)播放,reverse表示倒序播放 void setRepeatMode(@LottieDrawable.RepeatMode int mode) int getRepeatMode()

lottie_repeatCount 設(shè)定循環(huán)播放次數(shù),取值為整數(shù)類型。 void setRepeatCount(int count) int getRepeatCount()

lottie_imageAssetsFolder 設(shè)定圖片文件在assets文件夾下的訪問路徑。有的時(shí)候使用AE導(dǎo)出lottie的json時(shí)也會(huì)導(dǎo)出一些圖片,這時(shí)候就需要該屬性設(shè)定圖片的地址。 void setImageAssetsFolder(String imageAssetsFolder) String getImageAssetsFolder()

void setFrame(int frame) 將進(jìn)度設(shè)置為指定的幀。將進(jìn)度設(shè)置為指定的幀。如果尚未設(shè)置合成,則進(jìn)度將在設(shè)置時(shí)設(shè)置為幀。 通過int getFrame()可以獲取當(dāng)前渲染的幀。

void setMaxFrame(int endFrame) 設(shè)置播放或循環(huán)時(shí)動(dòng)畫將結(jié)束的最大幀。 該值將被鉗制到合成邊界。例如,設(shè)置整數(shù)最大值將產(chǎn)生與合成相同的結(jié)果。 通過float getMaxFrame()可以獲取當(dāng)前設(shè)定的最大幀

void setMinFrame(int startFrame) 設(shè)置播放或循環(huán)時(shí)動(dòng)畫開始的最小幀。 設(shè)定最大、最小幀可以只播放lottie動(dòng)畫中的一部分,例如下面的兩張圖,第一張是完整的從0播放到183幀,第二張則是從60播放到100幀。

Android車載HMI—Lottie講解插圖4

lottie_progress 設(shè)定動(dòng)畫初次顯示時(shí)的進(jìn)度,類型為float。取值范圍0.0 ~ 1.0 void setProgress(@FloatRange(from = 0f, to = 1f) float progress) float getProgress()

lottie_speed 設(shè)定播放速度,取值類型為float。當(dāng)速度<1時(shí),動(dòng)畫會(huì)慢放,當(dāng)速度<0時(shí),可以實(shí)現(xiàn)倒序播放。 void setSpeed(float speed) float getSpeed() void reverseAnimationSpeed():反轉(zhuǎn)當(dāng)前動(dòng)畫速度。這不會(huì)播放動(dòng)畫。

Android車載HMI—Lottie講解插圖5

速度是一個(gè)比較重要的屬性,與progress、frame等屬性一起靈活運(yùn)用,我們就可以輕松地在HMI上實(shí)現(xiàn)炫酷而復(fù)雜的儀表盤效果,這對(duì)車載HMI尤為重要。

lottie_enableMergePathsForKitKatAndAbove 設(shè)定是否開啟MergePath屬性,取值為true | false。默認(rèn)為false void enableMergePathsForKitKatAndAbove(boolean enable) boolean isMergePathsEnabledForKitKatAndAbove()

void playAnimation() 從頭開始播放動(dòng)畫。如果速度<0,它將從終點(diǎn)開始,并向起點(diǎn)播放。必須在主線程中調(diào)用。

void cancelAnimation() 取消動(dòng)畫,必須在主線程中調(diào)用。

void pauseAnimation() 暫停動(dòng)畫,必須在主線程中調(diào)用。

void resumeAnimation() 從當(dāng)前位置繼續(xù)播放動(dòng)畫。如果速度<0,它將從當(dāng)前位置向后播放。必須在主線程中調(diào)用。

long getDuration() 獲取動(dòng)畫的播放時(shí)長(zhǎng)。

void setTextDelegate(TextDelegate textDelegate) 設(shè)置此選項(xiàng)可在運(yùn)行時(shí)用自定義文本替換動(dòng)畫文本

lottie_cacheComposition 設(shè)定是否開啟緩存,取值 true | false,默認(rèn)開啟。開啟緩存可以提升動(dòng)畫的加載效率。

void setCacheComposition(boolean cacheComposition)
lottie_ignoreDisabledSystemAnimations 允許忽略系統(tǒng)動(dòng)畫設(shè)置,因此即使禁用動(dòng)畫,也允許運(yùn)行動(dòng)畫。取值 true | false,默認(rèn)為false。 void setIgnoreDisabledSystemAnimations(boolean ignore)lottie_clipToCompositionBounds 設(shè)置lottie是否應(yīng)剪輯到原始動(dòng)畫合成邊界。設(shè)置為true時(shí),父視圖可能需要禁用clipChildren,以便Lottie可以在LottieAnimationView邊界之外進(jìn)行渲染。默認(rèn)為true。 void setClipToCompositionBounds(boolean clipToCompositionBounds)lottie_renderMode 設(shè)定渲染模式,取值為 automatic | hardware | software。設(shè)定渲染模式為hardware時(shí),可以顯著提升動(dòng)畫的渲染效率,但是有些系統(tǒng)函數(shù)可能并不支持硬件加速,實(shí)際使用時(shí)需要結(jié)合調(diào)試時(shí)的效果選擇是否開啟。 void setRenderMode(RenderMode renderMode) RenderMode getRenderMode()void addAnimatorListener(Animator.AnimatorListener listener) 添加動(dòng)畫的屬性監(jiān)聽。 對(duì)應(yīng)也提供了removeUpdateListener(ValueAnimator.AnimatorUpdateListener updateListener)用來移除指定的監(jiān)聽?;蛘咭部梢允褂胷emoveAllAnimatorListeners()移除所有監(jiān)聽。
binding.animationView.addAnimatorUpdateListener(object : ValueAnimator.AnimatorUpdateListener { override fun onAnimationUpdate(animation: ValueAnimator?) { } })
void addAnimatorPauseListener(Animator.AnimatorPauseListener listener) 添加動(dòng)畫暫停/恢復(fù)監(jiān)聽。 對(duì)應(yīng)也提供了removeAnimatorPauseListener(Animator.AnimatorPauseListener listener)用來移除指定的監(jiān)聽。
binding.animationView.addAnimatorPauseListener(object : Animator.AnimatorPauseListener{ override fun onAnimationPause(animation: Animator?) { } override fun onAnimationResume(animation: Animator?) { } })
void addAnimatorUpdateListener(ValueAnimator.AnimatorUpdateListener updateListener) 添加動(dòng)畫發(fā)生更新時(shí)的監(jiān)聽 對(duì)應(yīng)也提供了removeUpdateListener(ValueAnimator.AnimatorUpdateListener updateListener)用來移除指定的監(jiān)聽?;蛘咭部梢允褂胷emoveAllUpdateListeners()移除所有監(jiān)聽。
binding.animationView.addAnimatorUpdateListener(object : ValueAnimator.AnimatorUpdateListener{ override fun onAnimationUpdate(animation: ValueAnimator?) { } })
void addValueCallback(KeyPath keyPath, T property, LottieValueCallback callback)

監(jiān)聽lottie動(dòng)畫json中某個(gè)片段的屬性。

keypath

可以解析為多個(gè)內(nèi)容,在這種情況下,回調(diào)的值將應(yīng)用于所有回調(diào)。在內(nèi)部會(huì)首先檢查是否已使用resolveKeyPath(KeyPath)解析keypath,如果尚未解析,則將對(duì)其進(jìn)行解析。

Android車載HMI—Lottie講解插圖6
img

Lottie動(dòng)畫的Json中屬性都是英文簡(jiǎn)寫,我們很難把json中key與實(shí)際的屬性對(duì)應(yīng)起來,所以有了第二個(gè)參數(shù)

LottieProperty

,它的內(nèi)部定義了大量的屬性,當(dāng)我們需要修改json時(shí),只需要傳入

LottieProperty

中屬性即可。

例如,需要監(jiān)聽json中

LeftArmWave

的持續(xù)時(shí)間,就可以這么寫

animationView.addValueCallback(KeyPath(“LeftArmWave”),LottieProperty.TIME_REMAP){frameInfo-> }

4.Lottie的常見用法

Lottie的Demo中內(nèi)置了很多官方自己開發(fā)的動(dòng)畫效果,目的是為我們展示Lottie的常見用法,作為開發(fā)者我們必須掌握,并在適當(dāng)?shù)臅r(shí)候運(yùn)用到我們的應(yīng)用中。

動(dòng)態(tài)屬性效果

該效果展示了lottie支持動(dòng)態(tài)修改json,讓動(dòng)畫中的一小部分屬性發(fā)生改變。

修改局部動(dòng)畫的速度
binding.animationView.addValueCallback(KeyPath(“LeftArmWave”),LottieProperty.TIME_REMAP){frameInfo-> 2*speed.toFloat()*frameInfo.overallProgress}

KeyPath中的LeftArmWave是Json中的一個(gè)屬性

Android車載HMI—Lottie講解插圖7
img

修改的效果如下。注意看右手的擺動(dòng)頻率X3后比X1高,以至于錄制的GIF直接丟幀了。

Android車載HMI—Lottie講解插圖8
修改局部動(dòng)畫的顏色
val shirt = KeyPath(“Shirt”, “Group 5”, “Fill 1”) val leftArm = KeyPath(“LeftArmWave”, “LeftArm”, “Group 6”, “Fill 1”) val rightArm = KeyPath(“RightArm”, “Group 6”, “Fill 1”) binding.animationView.addValueCallback(shirt, LottieProperty.COLOR) { COLORS[colorIndex] } binding.animationView.addValueCallback(leftArm, LottieProperty.COLOR) { COLORS[colorIndex] } binding.animationView.addValueCallback(rightArm, LottieProperty.COLOR) { COLORS[colorIndex] }

修改后的效果如下

Android車載HMI—Lottie講解插圖9
修改局部動(dòng)畫的運(yùn)動(dòng)范圍
val point = PointF() binding.animationView.addValueCallback( KeyPath(“Body”), LottieProperty.TRANSFORM_POSITION ) { frameInfo -> val startX = frameInfo.startValue.x var startY = frameInfo.startValue.y var endY = frameInfo.endValue.y if (startY > endY) { startY += EXTRA_JUMP[extraJumpIndex] } else if (endY > startY) { endY += EXTRA_JUMP[extraJumpIndex] } point.set(startX, lerp(startY, endY, frameInfo.interpolatedKeyframeProgress)) point }

修改后的效果如下

Android車載HMI—Lottie講解插圖10

動(dòng)畫文字效果

Android車載HMI—Lottie講解插圖11
img

該效果展示了動(dòng)畫文字效果。這個(gè)效果實(shí)現(xiàn)起來其實(shí)不難,從程序中捕獲輸入的字母,再替換成lottie的資源文件即可。

val letter = “” + Character.toUpperCase(event.unicodeChar.toChar()) val fileName = “Mobilo/$letter.json” LottieCompositionFactory.fromAsset(context, fileName) .addListener { addComposition(it) }

動(dòng)態(tài)文字效果

Android車載HMI—Lottie講解插圖12

該效果展示動(dòng)態(tài)替換動(dòng)畫中的文字。使用就可以在動(dòng)畫運(yùn)行中修改lottie動(dòng)畫中的文字

val textDelegate = TextDelegate(binding.dynamicTextView) binding.nameEditText.addTextChangedListener(object : TextWatcher { override fun afterTextChanged(s: Editable?) { textDelegate.setText(“NAME”, s.toString()) } override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} }) binding.dynamicTextView.setTextDelegate(textDelegate)

注意,這里其實(shí)用了兩個(gè)lottieView,分別設(shè)定了不同的文字。

<LinearLayout android:layout_width=“match_parent” android:layout_height=“wrap_content” android:layout_gravity=“center_horizontal” android:orientation=“horizontal”> <com.airbnb.lottie.LottieAnimationView android:id=“@+id/originalTextView” android:layout_width=“wrap_content” android:layout_height=“wrap_content” android:layout_marginRight=“16dp” app:lottie_rawRes=“@raw/name” app:lottie_autoPlay=“true” app:lottie_loop=“true”/> <com.airbnb.lottie.LottieAnimationView android:id=“@+id/dynamicTextView” android:layout_width=“wrap_content” android:layout_height=“wrap_content” app:lottie_rawRes=“@raw/name” app:lottie_autoPlay=“true” app:lottie_loop=“true”/> </LinearLayout>

手勢(shì)交互效果

Android車載HMI—Lottie講解插圖13

該效果展示了Lottie的手勢(shì)交互。其實(shí)和第一個(gè)效果實(shí)現(xiàn)思路相同,都是通過修改json中的屬性來實(shí)現(xiàn)的。

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val largeValueCallback = LottieRelativePointValueCallback(PointF(0f, 0f)) binding.animationView.addValueCallback(KeyPath(“First”), LottieProperty.TRANSFORM_POSITION, largeValueCallback) val mediumValueCallback = LottieRelativePointValueCallback(PointF(0f, 0f)) binding.animationView.addValueCallback(KeyPath(“Fourth”), LottieProperty.TRANSFORM_POSITION, mediumValueCallback) val smallValueCallback = LottieRelativePointValueCallback(PointF(0f, 0f)) binding.animationView.addValueCallback(KeyPath(“Seventh”), LottieProperty.TRANSFORM_POSITION, smallValueCallback) var totalDx = 0f var totalDy = 0f val viewDragHelper = ViewDragHelper.create(binding.containerView, object : ViewDragHelper.Callback() { override fun tryCaptureView(child: View, pointerId: Int) = child == binding.targetView override fun clampViewPositionVertical(child: View, top: Int, dy: Int): Int { return top } override fun clampViewPositionHorizontal(child: View, left: Int, dx: Int): Int { return left } override fun onViewPositionChanged(changedView: View, left: Int, top: Int, dx: Int, dy: Int) { totalDx += dx totalDy += dy smallValueCallback.setValue(getPoint(totalDx, totalDy, 1.2f)) mediumValueCallback.setValue(getPoint(totalDx, totalDy, 1f)) largeValueCallback.setValue(getPoint(totalDx, totalDy, 0.75f)) } }) binding.containerView.viewDragHelper = viewDragHelper }

在RecyclerView中使用

Android車載HMI—Lottie講解插圖14

該效果展示通過監(jiān)聽點(diǎn)擊事件來播放不同的lottie動(dòng)畫。這個(gè)效果最常見,APP中的點(diǎn)贊效果大多都是這樣的實(shí)現(xiàn)思路。

以上就是車載HMI—Lottie的一些講解。更多有關(guān)車載可以參考BYD高工整理出的《車載技術(shù)開發(fā)手冊(cè)》,市面上車載技術(shù)資料少之又少;希望這本電子手冊(cè)能夠幫助到你。

5.總結(jié)

在車載HMI開發(fā)中往往我們會(huì)在實(shí)現(xiàn)、調(diào)試UI上花費(fèi)大量的時(shí)間,如果能夠靈活的運(yùn)用Lottie,就可以顯著節(jié)省程序的開發(fā)時(shí)間。例如,光影、粒子等特效雖然可以也考慮用Kanzi等3D引擎實(shí)現(xiàn),但是3D引擎會(huì)消耗成倍的SOC性能,實(shí)際開發(fā)過程中,簡(jiǎn)單的特效使用Lottie實(shí)現(xiàn),可以極大的優(yōu)化應(yīng)用的性能,給用戶一個(gè)更優(yōu)秀的體驗(yàn)。

該效果展示通過監(jiān)聽點(diǎn)擊事件來播放不同的lottie動(dòng)畫。這個(gè)效果最常見,APP中的點(diǎn)贊效果大多都是這樣的實(shí)現(xiàn)思路。

轉(zhuǎn)載:https://www.jianshu.com/p/2388c72d5aff

以上就是車載HMI—Lottie的一些講解。更多有關(guān)車載可以參考BYD高工整理出的《車載技術(shù)開發(fā)手冊(cè)》,市面上車載技術(shù)資料少之又少;希望這本電子手冊(cè)能夠幫助到你。

Android車載HMI—Lottie講解插圖15

聯(lián)系我們

聯(lián)系我們

0769-81627526

在線咨詢: QQ交談

郵箱: info@kingpo.hk

工作時(shí)間:周一至周五,9:00-17:30,節(jié)假日休息
關(guān)注微信
微信掃一掃關(guān)注我們

微信掃一掃關(guān)注我們

手機(jī)訪問
手機(jī)掃一掃打開網(wǎng)站

手機(jī)掃一掃打開網(wǎng)站

返回頂部
成武县| 会昌县| 峨山| 湖口县| 二连浩特市| 昌乐县| 大新县| 富裕县| 乐安县| 禄丰县| 秦安县| 邮箱| 北安市| 扬州市|