Android Flip 3D Animation like web G+.
Card_gratification.xml
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_start"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintGuide_percent=".30" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_end"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintGuide_percent=".70" />
<ImageView
android:id="@+id/btn_share_achievement"
android:layout_width="@dimen/button_height"
android:layout_height="@dimen/button_height"
android:background="?attr/selectableItemBackgroundBorderless"
android:padding="@dimen/card_padding"
android:src="@drawable/ic_share_dashboard_card"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/img_gratification"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="@id/guide_end"
app:layout_constraintStart_toStartOf="@id/guide_start"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias=".25"
app:lottie_autoPlay="true"
app:lottie_loop="false" />
<TextView
android:id="@+id/txt_gratification"
style="@style/SansMediumXMediumTextViewStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/goal_achieved"
android:textColor="@color/text_color_black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/img_gratification"
app:layout_constraintVertical_bias=".23" />
<TextView
android:id="@+id/btn_got_it"
style="@style/SansSmallMediumTextViewStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:text="@string/got_it"
android:textAllCaps="true"
android:textColor="@color/water_track_accent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/txt_gratification" />
</androidx.constraintlayout.widget.ConstraintLayout>
card_water_tracker.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/water_progress_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/shadow_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_start"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintGuide_percent=".30" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_end"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintGuide_percent=".70" />
<com.github.lzyzsd.circleprogress.DonutProgress
android:id="@+id/dp_water_progress"
android:layout_width="0dp"
android:layout_height="0dp"
android:rotation="-90"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="@id/guide_end"
app:layout_constraintStart_toStartOf="@id/guide_start"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias=".25"
custom:donut_finished_color="@color/new_water_track_button_blue"
custom:donut_finished_stroke_width="@dimen/small_padding"
custom:donut_progress="0"
custom:donut_text_color="@color/transparent"
custom:donut_unfinished_color="@color/activity_background_grey"
custom:donut_unfinished_stroke_width="@dimen/small_padding" />
<ImageView
android:id="@+id/img_glass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/small_padding"
android:src="@drawable/ic_water_hydration_glass"
app:layout_constraintBottom_toBottomOf="@id/dp_water_progress"
app:layout_constraintEnd_toEndOf="@id/dp_water_progress"
app:layout_constraintStart_toStartOf="@id/dp_water_progress"
app:layout_constraintTop_toTopOf="@id/dp_water_progress"
app:tint="@color/water_track_accent" />
<ImageView
android:id="@+id/btn_add_glass"
android:layout_width="@dimen/button_height"
android:layout_height="@dimen/button_height"
android:background="?attr/selectableItemBackgroundBorderless"
android:paddingStart="@dimen/card_padding"
android:paddingTop="@dimen/card_padding_more"
android:paddingEnd="@dimen/content_gutter"
android:paddingBottom="@dimen/card_padding_more"
android:scaleType="fitXY"
android:src="@drawable/ic_water_plus"
app:layout_constraintBottom_toBottomOf="@id/img_glass"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintStart_toEndOf="@id/dp_water_progress"
app:layout_constraintTop_toTopOf="@id/img_glass" />
<ImageView
android:id="@+id/btn_remove_glass"
android:layout_width="@dimen/button_height"
android:layout_height="@dimen/button_height"
android:background="?attr/selectableItemBackgroundBorderless"
android:paddingStart="@dimen/content_gutter"
android:paddingTop="@dimen/card_padding_more"
android:paddingEnd="@dimen/card_padding"
android:paddingBottom="@dimen/card_padding_more"
android:scaleType="fitXY"
android:src="@drawable/ic_water_minus"
app:layout_constraintBottom_toBottomOf="@id/img_glass"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toStartOf="@id/dp_water_progress"
app:layout_constraintTop_toTopOf="@id/img_glass" />
<TextView
android:id="@+id/txt_water_goal"
style="@style/SansMediumXMediumTextViewStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/text_color_black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/dp_water_progress"
app:layout_constraintVertical_bias=".23"
tools:text="5 of 10" />
<TextView
android:id="@+id/txt_water"
style="@style/SansRegularSmallTextViewStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/small_padding"
android:textColor="@color/disabled_text_color"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/txt_water_goal"
tools:text="5 of 10" />
</androidx.constraintlayout.widget.ConstraintLayout>
Including both layouts in one xml.
<?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:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/water_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/view_gratification"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
android:background="@drawable/shadow_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<include
layout="@layout/card_gratification"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<!-- Add card_water_tracker.xml here-->
</androidx.constraintlayout.widget.ConstraintLayout>
flip_out.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="1500"
android:propertyName="rotationY"
android:valueFrom="0"
android:valueTo="180" />
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:startOffset="750"
android:valueFrom="1.0"
android:valueTo="0.0" />
</set>
flip_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:valueFrom="1.0"
android:valueTo="0.0" />
<objectAnimator
android:duration="1500"
android:propertyName="rotationY"
android:repeatMode="reverse"
android:valueFrom="-180"
android:valueTo="0" />
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:startOffset="750"
android:valueFrom="0.0"
android:valueTo="1.0" />
</set>
visibleView — view that you want to bring in front
fun flipCard(context: Context, visibleView: View, inVisibleView: View) {
try {
visibleView.visible()
val flipOutAnimatorSet =
AnimatorInflater.loadAnimator(
context,
R.animator.flip_out
) as AnimatorSet
flipOutAnimatorSet.setTarget(inVisibleView)
val flipInAnimationSet =
AnimatorInflater.loadAnimator(
context,
R.animator.flip_in
) as AnimatorSet
flipInAnimationSet.setTarget(visibleView)
flipOutAnimatorSet.start()
flipInAnimationSet.start()
flipInAnimatorSet.doOnEnd {
inVisibleView.gone()
}
} catch (e: Exception) {
logHandledException(e)
}
}
inVisibleView — View that you want to push back
fun flipCard(context: Context, visibleView: View, inVisibleView: View) {
try {
visibleView.visible()
val scale = context.resources.displayMetrics.density
val cameraDist = 8000 * scale
visibleView.cameraDistance = cameraDist
inVisibleView.cameraDistance = cameraDist
val flipOutAnimatorSet =
AnimatorInflater.loadAnimator(
context,
R.animator.flip_out
) as AnimatorSet
flipOutAnimatorSet.setTarget(inVisibleView)
val flipInAnimatorSet =
AnimatorInflater.loadAnimator(
context,
R.animator.flip_in
) as AnimatorSet
flipInAnimatorSet.setTarget(visibleView)
flipOutAnimatorSet.start()
flipInAnimatorSet.start()
flipInAnimatorSet.doOnEnd {
inVisibleView.gone()
}
} catch (e: Exception) {
logHandledException(e)
}
}
0 Comments: