kopia lustrzana https://github.com/ryukoposting/Signal-Android
Add animation when you directly react to a story.
rodzic
c0f843061e
commit
cdef21d6c0
|
@ -18,6 +18,7 @@ import androidx.core.view.GestureDetectorCompat
|
|||
import androidx.core.view.doOnNextLayout
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.setFragmentResultListener
|
||||
import androidx.fragment.app.viewModels
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
|
@ -45,6 +46,7 @@ import org.thoughtcrime.securesms.stories.dialogs.StoryContextMenu
|
|||
import org.thoughtcrime.securesms.stories.viewer.StoryViewerViewModel
|
||||
import org.thoughtcrime.securesms.stories.viewer.reply.direct.StoryDirectReplyDialogFragment
|
||||
import org.thoughtcrime.securesms.stories.viewer.reply.group.StoryGroupReplyBottomSheetDialogFragment
|
||||
import org.thoughtcrime.securesms.stories.viewer.reply.reaction.OnReactionSentView
|
||||
import org.thoughtcrime.securesms.stories.viewer.reply.tabs.StoryViewsAndRepliesDialogFragment
|
||||
import org.thoughtcrime.securesms.stories.viewer.text.StoryTextPostPreviewFragment
|
||||
import org.thoughtcrime.securesms.stories.viewer.views.StoryViewsBottomSheetDialogFragment
|
||||
|
@ -113,6 +115,7 @@ class StoryViewerPageFragment :
|
|||
val caption: TextView = view.findViewById(R.id.story_caption)
|
||||
val largeCaption: TextView = view.findViewById(R.id.story_large_caption)
|
||||
val largeCaptionOverlay: View = view.findViewById(R.id.story_large_caption_overlay)
|
||||
val reactionAnimationView: OnReactionSentView = view.findViewById(R.id.on_reaction_sent_view)
|
||||
|
||||
storySlate = view.findViewById(R.id.story_slate)
|
||||
progressBar = view.findViewById(R.id.progress)
|
||||
|
@ -204,6 +207,12 @@ class StoryViewerPageFragment :
|
|||
}
|
||||
}
|
||||
|
||||
reactionAnimationView.callback = object : OnReactionSentView.Callback {
|
||||
override fun onFinished() {
|
||||
viewModel.setIsDisplayingReactionAnimation(false)
|
||||
}
|
||||
}
|
||||
|
||||
sharedViewModel.isScrolling.observe(viewLifecycleOwner) { isScrolling ->
|
||||
viewModel.setIsUserScrollingParent(isScrolling)
|
||||
}
|
||||
|
@ -276,6 +285,14 @@ class StoryViewerPageFragment :
|
|||
}
|
||||
|
||||
adjustConstraintsForScreenDimensions(viewsAndReplies, cardWrapper, card)
|
||||
|
||||
childFragmentManager.setFragmentResultListener(StoryDirectReplyDialogFragment.REQUEST_EMOJI, viewLifecycleOwner) { _, bundle ->
|
||||
val emoji = bundle.getString(StoryDirectReplyDialogFragment.REQUEST_EMOJI)
|
||||
if (emoji != null) {
|
||||
reactionAnimationView.playForEmoji(emoji)
|
||||
viewModel.setIsDisplayingReactionAnimation(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
|
|
@ -135,6 +135,10 @@ class StoryViewerPageViewModel(
|
|||
storyViewerPlaybackStore.update { it.copy(isSelectedPage = isSelectedPage) }
|
||||
}
|
||||
|
||||
fun setIsDisplayingReactionAnimation(isDisplayingReactionAnimation: Boolean) {
|
||||
storyViewerPlaybackStore.update { it.copy(isDisplayingReactionAnimation = isDisplayingReactionAnimation) }
|
||||
}
|
||||
|
||||
fun setIsDisplayingContextMenu(isDisplayingContextMenu: Boolean) {
|
||||
storyViewerPlaybackStore.update { it.copy(isDisplayingContextMenu = isDisplayingContextMenu) }
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@ data class StoryViewerPlaybackState(
|
|||
val isSelectedPage: Boolean = false,
|
||||
val isDisplayingSlate: Boolean = false,
|
||||
val isFragmentResumed: Boolean = false,
|
||||
val isDisplayingLinkPreviewTooltip: Boolean = false
|
||||
val isDisplayingLinkPreviewTooltip: Boolean = false,
|
||||
val isDisplayingReactionAnimation: Boolean = false
|
||||
) {
|
||||
val isPaused: Boolean = !areSegmentsInitialized ||
|
||||
isUserTouching ||
|
||||
|
@ -28,5 +29,6 @@ data class StoryViewerPlaybackState(
|
|||
!isSelectedPage ||
|
||||
isDisplayingSlate ||
|
||||
!isFragmentResumed ||
|
||||
isDisplayingLinkPreviewTooltip
|
||||
isDisplayingLinkPreviewTooltip ||
|
||||
isDisplayingReactionAnimation
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.view.KeyEvent
|
|||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.setFragmentResult
|
||||
import androidx.fragment.app.viewModels
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
@ -146,6 +147,7 @@ class StoryDirectReplyDialogFragment :
|
|||
}
|
||||
|
||||
companion object {
|
||||
const val REQUEST_EMOJI = "request.code.emoji"
|
||||
|
||||
private const val ARG_STORY_ID = "arg.story.id"
|
||||
private const val ARG_RECIPIENT_ID = "arg.recipient.id"
|
||||
|
@ -180,7 +182,12 @@ class StoryDirectReplyDialogFragment :
|
|||
lifecycleDisposable += viewModel.sendReaction(emoji)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
// TODO [alex] -- Reaction explosion animation instead of toast.
|
||||
setFragmentResult(
|
||||
REQUEST_EMOJI,
|
||||
Bundle().apply {
|
||||
putString(REQUEST_EMOJI, emoji)
|
||||
}
|
||||
)
|
||||
Toast.makeText(requireContext(), R.string.StoryDirectReplyDialogFragment__reaction_sent, Toast.LENGTH_LONG).show()
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package org.thoughtcrime.securesms.stories.viewer.reply.reaction
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.FrameLayout
|
||||
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||
import androidx.constraintlayout.motion.widget.TransitionAdapter
|
||||
import androidx.core.view.doOnNextLayout
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||
import org.thoughtcrime.securesms.util.visible
|
||||
|
||||
class OnReactionSentView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null
|
||||
) : FrameLayout(context, attrs) {
|
||||
|
||||
var callback: Callback? = null
|
||||
|
||||
init {
|
||||
inflate(context, R.layout.on_reaction_sent_view, this)
|
||||
}
|
||||
|
||||
private val motionLayout: MotionLayout = findViewById(R.id.motion_layout)
|
||||
|
||||
init {
|
||||
motionLayout.addTransitionListener(object : TransitionAdapter() {
|
||||
override fun onTransitionCompleted(p0: MotionLayout?, p1: Int) {
|
||||
visible = false
|
||||
callback?.onFinished()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun playForEmoji(emoji: CharSequence) {
|
||||
motionLayout.progress = 0f
|
||||
motionLayout.visible = true
|
||||
|
||||
listOf(
|
||||
R.id.emoji_1,
|
||||
R.id.emoji_2,
|
||||
R.id.emoji_3,
|
||||
R.id.emoji_4,
|
||||
R.id.emoji_5,
|
||||
R.id.emoji_6,
|
||||
R.id.emoji_7,
|
||||
R.id.emoji_8,
|
||||
R.id.emoji_9,
|
||||
R.id.emoji_10,
|
||||
R.id.emoji_11,
|
||||
).forEach {
|
||||
findViewById<EmojiImageView>(it).setImageEmoji(emoji)
|
||||
}
|
||||
|
||||
motionLayout.requestLayout()
|
||||
motionLayout.doOnNextLayout {
|
||||
motionLayout.transitionToEnd()
|
||||
}
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
fun onFinished()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.motion.widget.MotionLayout 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:id="@+id/motion_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layoutDirection="ltr"
|
||||
app:layoutDescription="@xml/on_reaction_sent_view_scene"
|
||||
tools:showPaths="true">
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||
android:id="@+id/emoji_1"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
app:forceJumbo="true"
|
||||
app:layout_constraintTag="emoji"
|
||||
tools:background="@drawable/ic_heart_24" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||
android:id="@+id/emoji_2"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
app:forceJumbo="true"
|
||||
app:layout_constraintTag="emoji"
|
||||
tools:background="@drawable/ic_heart_24" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||
android:id="@+id/emoji_3"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
app:forceJumbo="true"
|
||||
app:layout_constraintTag="emoji"
|
||||
tools:background="@drawable/ic_heart_24" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||
android:id="@+id/emoji_4"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
app:forceJumbo="true"
|
||||
app:layout_constraintTag="emoji"
|
||||
tools:background="@drawable/ic_heart_24" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||
android:id="@+id/emoji_5"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
app:forceJumbo="true"
|
||||
app:layout_constraintTag="emoji"
|
||||
tools:background="@drawable/ic_heart_24" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||
android:id="@+id/emoji_6"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
app:forceJumbo="true"
|
||||
app:layout_constraintTag="emoji"
|
||||
tools:background="@drawable/ic_heart_24" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||
android:id="@+id/emoji_7"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
app:forceJumbo="true"
|
||||
app:layout_constraintTag="emoji"
|
||||
tools:background="@drawable/ic_heart_24" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||
android:id="@+id/emoji_8"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
app:forceJumbo="true"
|
||||
app:layout_constraintTag="emoji"
|
||||
tools:background="@drawable/ic_heart_24"
|
||||
tools:layout_editor_absoluteX="20dp"
|
||||
tools:layout_editor_absoluteY="591dp" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||
android:id="@+id/emoji_9"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
app:forceJumbo="true"
|
||||
app:layout_constraintTag="emoji"
|
||||
tools:background="@drawable/ic_heart_24" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||
android:id="@+id/emoji_10"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
app:forceJumbo="true"
|
||||
app:layout_constraintTag="emoji"
|
||||
tools:background="@drawable/ic_heart_24" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||
android:id="@+id/emoji_11"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
app:forceJumbo="true"
|
||||
app:layout_constraintTag="emoji"
|
||||
tools:background="@drawable/ic_heart_24" />
|
||||
|
||||
</androidx.constraintlayout.motion.widget.MotionLayout>
|
|
@ -243,4 +243,9 @@
|
|||
app:totalSegments="0"
|
||||
tools:totalSegments="5" />
|
||||
|
||||
<org.thoughtcrime.securesms.stories.viewer.reply.reaction.OnReactionSentView
|
||||
android:id="@+id/on_reaction_sent_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,375 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:motion="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<ConstraintSet android:id="@+id/start">
|
||||
<Constraint
|
||||
android:id="@+id/emoji_1"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toBottomOf="parent" />
|
||||
<Constraint
|
||||
android:id="@+id/emoji_2"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginEnd="80dp"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toBottomOf="parent" />
|
||||
<Constraint
|
||||
android:id="@id/emoji_3"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginEnd="56dp"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
motion:layout_constraintBottom_toTopOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent" />
|
||||
<Constraint
|
||||
android:id="@+id/emoji_4"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toBottomOf="parent" />
|
||||
<Constraint
|
||||
android:id="@+id/emoji_5"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_marginStart="60dp"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toBottomOf="parent" />
|
||||
<Constraint
|
||||
android:id="@+id/emoji_6"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginEnd="40dp"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintTop_toBottomOf="parent" />
|
||||
<Constraint
|
||||
android:id="@+id/emoji_7"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toBottomOf="parent" />
|
||||
<Constraint
|
||||
android:id="@+id/emoji_8"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toBottomOf="parent" />
|
||||
<Constraint
|
||||
android:id="@+id/emoji_9"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toBottomOf="parent" />
|
||||
<Constraint
|
||||
android:id="@+id/emoji_10"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toBottomOf="parent" />
|
||||
<Constraint
|
||||
android:id="@+id/emoji_11"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:scaleX="0"
|
||||
android:scaleY="0"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintTop_toBottomOf="parent" />
|
||||
</ConstraintSet>
|
||||
|
||||
<ConstraintSet android:id="@+id/end">
|
||||
<Constraint
|
||||
android:id="@id/emoji_1"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
motion:layout_constraintBottom_toTopOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent" />
|
||||
<Constraint
|
||||
android:id="@id/emoji_2"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginEnd="80dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
motion:layout_constraintBottom_toTopOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent" />
|
||||
<Constraint
|
||||
android:id="@id/emoji_3"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginEnd="56dp"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
motion:layout_constraintBottom_toTopOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent" />
|
||||
<Constraint
|
||||
android:id="@id/emoji_4"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
motion:layout_constraintBottom_toTopOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent" />
|
||||
<Constraint
|
||||
android:id="@id/emoji_5"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_marginStart="60dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
motion:layout_constraintBottom_toTopOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent" />
|
||||
<Constraint
|
||||
android:id="@id/emoji_6"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginEnd="40dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
motion:layout_constraintBottom_toTopOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent" />
|
||||
<Constraint
|
||||
android:id="@id/emoji_7"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
motion:layout_constraintBottom_toTopOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent" />
|
||||
<Constraint
|
||||
android:id="@id/emoji_8"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
motion:layout_constraintBottom_toTopOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent" />
|
||||
<Constraint
|
||||
android:id="@+id/emoji_9"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
motion:layout_constraintEnd_toEndOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent"
|
||||
motion:layout_constraintTop_toBottomOf="parent" />
|
||||
<Constraint
|
||||
android:id="@id/emoji_10"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
motion:layout_constraintBottom_toTopOf="parent"
|
||||
motion:layout_constraintStart_toStartOf="parent" />
|
||||
<Constraint
|
||||
android:id="@id/emoji_11"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:scaleX="1"
|
||||
android:scaleY="1"
|
||||
motion:layout_constraintBottom_toTopOf="parent"
|
||||
motion:layout_constraintEnd_toEndOf="parent" />
|
||||
</ConstraintSet>
|
||||
|
||||
<Transition
|
||||
motion:constraintSetEnd="@id/end"
|
||||
motion:constraintSetStart="@id/start"
|
||||
motion:duration="2500"
|
||||
motion:motionInterpolator="cubic(0.25,0.25,0.5,1)">
|
||||
|
||||
<KeyFrameSet>
|
||||
<KeyAttribute
|
||||
android:scaleX="1"
|
||||
motion:framePosition="40"
|
||||
motion:motionTarget="emoji" />
|
||||
<KeyAttribute
|
||||
android:scaleY="1"
|
||||
motion:framePosition="40"
|
||||
motion:motionTarget="emoji" />
|
||||
<KeyCycle
|
||||
android:rotation="24"
|
||||
motion:framePosition="0"
|
||||
motion:motionTarget="@+id/emoji_1"
|
||||
motion:waveOffset="0"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="24"
|
||||
motion:framePosition="100"
|
||||
motion:motionTarget="@+id/emoji_1"
|
||||
motion:waveOffset="0"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="15"
|
||||
motion:framePosition="0"
|
||||
motion:motionTarget="@+id/emoji_2"
|
||||
motion:waveOffset="-15"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="15"
|
||||
motion:framePosition="100"
|
||||
motion:motionTarget="@+id/emoji_2"
|
||||
motion:waveOffset="-15"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="8"
|
||||
motion:framePosition="0"
|
||||
motion:motionTarget="@+id/emoji_3"
|
||||
motion:waveOffset="0"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="8"
|
||||
motion:framePosition="100"
|
||||
motion:motionTarget="@+id/emoji_3"
|
||||
motion:waveOffset="0"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="12"
|
||||
motion:framePosition="0"
|
||||
motion:motionTarget="@+id/emoji_4"
|
||||
motion:waveOffset="0"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="12"
|
||||
motion:framePosition="100"
|
||||
motion:motionTarget="@+id/emoji_4"
|
||||
motion:waveOffset="0"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="12"
|
||||
motion:framePosition="0"
|
||||
motion:motionTarget="@+id/emoji_5"
|
||||
motion:waveOffset="0"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="12"
|
||||
motion:framePosition="100"
|
||||
motion:motionTarget="@+id/emoji_5"
|
||||
motion:waveOffset="0"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="10"
|
||||
motion:framePosition="0"
|
||||
motion:motionTarget="@+id/emoji_8"
|
||||
motion:waveOffset="2"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="10"
|
||||
motion:framePosition="100"
|
||||
motion:motionTarget="@+id/emoji_8"
|
||||
motion:waveOffset="2"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="6"
|
||||
motion:framePosition="0"
|
||||
motion:motionTarget="@+id/emoji_11"
|
||||
motion:waveOffset="2"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyCycle
|
||||
android:rotation="6"
|
||||
motion:framePosition="100"
|
||||
motion:motionTarget="@+id/emoji_11"
|
||||
motion:waveOffset="2"
|
||||
motion:wavePeriod="1" />
|
||||
<KeyPosition
|
||||
motion:framePosition="40"
|
||||
motion:keyPositionType="deltaRelative"
|
||||
motion:motionTarget="@+id/emoji_1"
|
||||
motion:percentY="1" />
|
||||
<KeyPosition
|
||||
motion:framePosition="44"
|
||||
motion:keyPositionType="deltaRelative"
|
||||
motion:motionTarget="@+id/emoji_2"
|
||||
motion:percentY="1" />
|
||||
<KeyPosition
|
||||
motion:framePosition="72"
|
||||
motion:keyPositionType="deltaRelative"
|
||||
motion:motionTarget="@+id/emoji_3"
|
||||
motion:percentY="1" />
|
||||
<KeyPosition
|
||||
motion:framePosition="52"
|
||||
motion:keyPositionType="deltaRelative"
|
||||
motion:motionTarget="@+id/emoji_4"
|
||||
motion:percentY="1" />
|
||||
<KeyPosition
|
||||
motion:framePosition="56"
|
||||
motion:keyPositionType="deltaRelative"
|
||||
motion:motionTarget="@+id/emoji_5"
|
||||
motion:percentY="1" />
|
||||
<KeyPosition
|
||||
motion:framePosition="48"
|
||||
motion:keyPositionType="deltaRelative"
|
||||
motion:motionTarget="@+id/emoji_6"
|
||||
motion:percentY="1" />
|
||||
<KeyPosition
|
||||
motion:framePosition="64"
|
||||
motion:keyPositionType="deltaRelative"
|
||||
motion:motionTarget="@+id/emoji_7"
|
||||
motion:percentY="1" />
|
||||
<KeyPosition
|
||||
motion:framePosition="68"
|
||||
motion:keyPositionType="deltaRelative"
|
||||
motion:motionTarget="@+id/emoji_8"
|
||||
motion:percentY="1" />
|
||||
<KeyPosition
|
||||
motion:framePosition="80"
|
||||
motion:keyPositionType="deltaRelative"
|
||||
motion:motionTarget="@+id/emoji_9"
|
||||
motion:percentY="1" />
|
||||
<KeyPosition
|
||||
motion:framePosition="88"
|
||||
motion:keyPositionType="deltaRelative"
|
||||
motion:motionTarget="@+id/emoji_11"
|
||||
motion:percentY="1" />
|
||||
</KeyFrameSet>
|
||||
</Transition>
|
||||
</MotionScene>
|
Ładowanie…
Reference in New Issue