Add animations to camera toggle.

This commit is contained in:
Alex Hart
2022-03-24 09:01:05 -03:00
committed by Greyson Parrelli
parent e9160c2449
commit f6f4e6fde7
6 changed files with 165 additions and 95 deletions

View File

@@ -1,18 +1,24 @@
package org.thoughtcrime.securesms.mediasend.v2
import android.animation.ValueAnimator
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatDelegate
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.Navigation
import androidx.navigation.fragment.NavHostFragment
import androidx.transition.AutoTransition
import androidx.transition.TransitionManager
import com.google.android.material.animation.ArgbEvaluatorCompat
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.PassphraseRequiredActivity
import org.thoughtcrime.securesms.R
@@ -43,6 +49,11 @@ class MediaSelectionActivity :
EmojiSearchFragment.Callback,
SearchConfigurationProvider {
private var animateInShadowLayerValueAnimator: ValueAnimator? = null
private var animateInTextColorValueAnimator: ValueAnimator? = null
private var animateOutShadowLayerValueAnimator: ValueAnimator? = null
private var animateOutTextColorValueAnimator: ValueAnimator? = null
lateinit var viewModel: MediaSelectionViewModel
private val textViewModel: TextStoryPostCreationViewModel by viewModels()
@@ -69,9 +80,16 @@ class MediaSelectionActivity :
val factory = MediaSelectionViewModel.Factory(destination, transportOption, initialMedia, message, isReply, MediaSelectionRepository(this))
viewModel = ViewModelProvider(this, factory)[MediaSelectionViewModel::class.java]
val textStoryToggle: ViewGroup = findViewById(R.id.switch_widget)
val textSwitch: View = findViewById(R.id.text_switch)
val cameraSwitch: View = findViewById(R.id.camera_switch)
val textStoryToggle: ConstraintLayout = findViewById(R.id.switch_widget)
val cameraSelectedConstraintSet = ConstraintSet().apply {
clone(textStoryToggle)
}
val textSelectedConstraintSet = ConstraintSet().apply {
clone(this@MediaSelectionActivity, R.layout.media_selection_activity_text_selected_constraints)
}
val textSwitch: TextView = findViewById(R.id.text_switch)
val cameraSwitch: TextView = findViewById(R.id.camera_switch)
textSwitch.setOnClickListener {
viewModel.sendCommand(HudCommand.GoToText)
@@ -101,13 +119,17 @@ class MediaSelectionActivity :
when (d.id) {
R.id.mediaCaptureFragment -> {
textStoryToggle.visible = canDisplayStorySwitch()
textSwitch.isSelected = false
cameraSwitch.isSelected = true
animateTextStyling(cameraSwitch, textSwitch, 200)
TransitionManager.beginDelayedTransition(textStoryToggle, AutoTransition().setDuration(200))
cameraSelectedConstraintSet.applyTo(textStoryToggle)
}
R.id.textStoryPostCreationFragment -> {
textStoryToggle.visible = canDisplayStorySwitch()
textSwitch.isSelected = true
cameraSwitch.isSelected = false
animateTextStyling(textSwitch, cameraSwitch, 200)
TransitionManager.beginDelayedTransition(textStoryToggle, AutoTransition().setDuration(200))
textSelectedConstraintSet.applyTo(textStoryToggle)
}
else -> textStoryToggle.visible = false
}
@@ -116,6 +138,36 @@ class MediaSelectionActivity :
onBackPressedDispatcher.addCallback(OnBackPressed())
}
private fun animateTextStyling(selectedSwitch: TextView, unselectedSwitch: TextView, duration: Long) {
animateInShadowLayerValueAnimator?.cancel()
animateInTextColorValueAnimator?.cancel()
animateOutShadowLayerValueAnimator?.cancel()
animateOutTextColorValueAnimator?.cancel()
animateInShadowLayerValueAnimator = ValueAnimator.ofFloat(selectedSwitch.shadowRadius, 0f).apply {
this.duration = duration
addUpdateListener { selectedSwitch.setShadowLayer(it.animatedValue as Float, 0f, 0f, Color.BLACK) }
start()
}
animateInTextColorValueAnimator = ValueAnimator.ofInt(selectedSwitch.currentTextColor, Color.BLACK).apply {
setEvaluator(ArgbEvaluatorCompat.getInstance())
this.duration = duration
addUpdateListener { selectedSwitch.setTextColor(it.animatedValue as Int) }
start()
}
animateOutShadowLayerValueAnimator = ValueAnimator.ofFloat(unselectedSwitch.shadowRadius, 3f).apply {
this.duration = duration
addUpdateListener { unselectedSwitch.setShadowLayer(it.animatedValue as Float, 0f, 0f, Color.BLACK) }
start()
}
animateOutTextColorValueAnimator = ValueAnimator.ofInt(unselectedSwitch.currentTextColor, Color.WHITE).apply {
setEvaluator(ArgbEvaluatorCompat.getInstance())
this.duration = duration
addUpdateListener { unselectedSwitch.setTextColor(it.animatedValue as Int) }
start()
}
}
private fun canDisplayStorySwitch(): Boolean {
return Stories.isFeatureEnabled() &&
FeatureFlags.storiesTextPosts() &&

View File

@@ -1,12 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<shape
android:shape="rectangle">
<solid android:color="@color/white" />
<corners android:radius="42dp" />
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
</shape>
</item>
</selector>
<solid android:color="@color/white" />
<corners android:radius="42dp" />
</shape>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/transparent_black_40" />
<corners android:radius="52dp" />
</shape>

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="match_parent">
@@ -11,82 +12,54 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/switch_widget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="8dp"
android:background="@drawable/story_pill_toggle_background">
android:layout_marginBottom="8dp">
<FrameLayout
android:id="@+id/text_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<View
android:id="@+id/selected_pill"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/story_pill_button_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/camera_switch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
app:layout_constraintBottom_toBottomOf="@id/camera_switch"
app:layout_constraintEnd_toEndOf="@id/camera_switch"
app:layout_constraintStart_toStartOf="@id/camera_switch"
app:layout_constraintTop_toTopOf="@id/camera_switch" />
<TextView
android:id="@+id/camera_switch_mirror"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_gravity="center"
android:gravity="center"
android:paddingHorizontal="18dp"
android:text="@string/MediaSelectionActivity__camera"
android:textAppearance="@style/TextAppearance.Signal.Body2"
android:textColor="@color/story_pill_text_color"
android:visibility="invisible" />
<TextView
android:id="@+id/text_switch_actual"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_gravity="center"
android:gravity="center"
android:paddingHorizontal="18dp"
android:text="@string/MediaSelectionActivity__text"
android:textAppearance="@style/TextAppearance.Signal.Body2"
android:textColor="@color/story_pill_text_color" />
</FrameLayout>
<FrameLayout
<TextView
android:id="@+id/camera_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:layout_marginTop="2dp"
android:layout_marginBottom="2dp"
android:background="@drawable/story_pill_button_background"
android:layout_height="36sp"
android:gravity="center"
android:paddingHorizontal="18dp"
android:shadowColor="@color/black"
android:text="@string/MediaSelectionActivity__camera"
android:textAppearance="@style/TextAppearance.Signal.Body2"
android:textColor="@color/story_pill_text_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/text_switch"
app:layout_constraintTop_toTopOf="parent">
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:background="@color/red" />
<TextView
android:id="@+id/text_switch_mirror"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_gravity="center"
android:gravity="center"
android:paddingHorizontal="18dp"
android:text="@string/MediaSelectionActivity__text"
android:textAppearance="@style/TextAppearance.Signal.Body2"
android:textColor="@color/story_pill_text_color"
android:visibility="invisible" />
<TextView
android:id="@+id/camera_switch_actual"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:layout_gravity="center"
android:gravity="center"
android:paddingHorizontal="18dp"
android:text="@string/MediaSelectionActivity__camera"
android:textAppearance="@style/TextAppearance.Signal.Body2"
android:textColor="@color/story_pill_text_color" />
</FrameLayout>
<TextView
android:id="@+id/text_switch"
android:layout_width="wrap_content"
android:layout_height="36sp"
android:gravity="center"
android:paddingHorizontal="18dp"
android:shadowColor="@color/black"
android:shadowRadius="3"
android:text="@string/MediaSelectionActivity__text"
android:textAppearance="@style/TextAppearance.Signal.Body2"
android:textColor="@color/story_pill_text_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/camera_switch"
app:layout_constraintTop_toTopOf="parent"
tools:background="@color/green" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View File

@@ -0,0 +1,52 @@
<?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:id="@+id/switch_widget"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="8dp">
<View
android:id="@+id/selected_pill"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/white"
app:layout_constraintBottom_toBottomOf="@id/text_switch"
app:layout_constraintEnd_toEndOf="@id/text_switch"
app:layout_constraintStart_toStartOf="@id/text_switch"
app:layout_constraintTop_toTopOf="@id/text_switch" />
<TextView
android:id="@+id/camera_switch"
android:layout_width="wrap_content"
android:layout_height="36sp"
android:gravity="center"
android:paddingHorizontal="18dp"
android:text="@string/MediaSelectionActivity__camera"
android:textAppearance="@style/TextAppearance.Signal.Body2"
android:textColor="@color/story_pill_text_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/text_switch"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:background="@color/red" />
<TextView
android:id="@+id/text_switch"
android:layout_width="wrap_content"
android:layout_height="36sp"
android:gravity="center"
android:paddingHorizontal="18dp"
android:text="@string/MediaSelectionActivity__text"
android:textAppearance="@style/TextAppearance.Signal.Body2"
android:textColor="@color/story_pill_text_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:background="@color/green" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -15,7 +15,11 @@
app:destination="@id/mediaGalleryFragment" />
<action
android:id="@+id/action_mediaCaptureFragment_to_textStoryPostCreationFragment"
app:destination="@id/textStoryPostCreationFragment" />
app:destination="@id/textStoryPostCreationFragment"
app:enterAnim="@anim/slide_from_end"
app:exitAnim="@null"
app:popEnterAnim="@null"
app:popExitAnim="@anim/slide_to_end" />
</fragment>
<fragment
@@ -43,7 +47,7 @@
android:id="@+id/textStoryPostCreationFragment"
android:name="org.thoughtcrime.securesms.mediasend.v2.text.TextStoryPostCreationFragment"
android:label="text_story_post_creation_fragment"
tools:layout="@layout/stories_text_post_creation_fragment" >
tools:layout="@layout/stories_text_post_creation_fragment">
<action
android:id="@+id/action_textStoryPostCreationFragment_to_textStoryPostSendFragment"
app:destination="@id/textStoryPostSendFragment" />