Simulate a 3D Flip by Using Android’s ScaleAnimation
In this article, we will learn to flip an image to another image like the card’s front and the card’s back as we see the virtual card in Paytm. For this, we will use Android’s ScaleAnimation. A sample GIF is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Kotlin language.
Step by Step Implementation
Step 1: Create a New Project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Kotlin as the programming language.
Step 2: Set orientation to Portrait mode
Because this is a graphics-intensive application, we expect the orientation to be maintained throughout, navigate to AndroidManifest.xml file and add the android:screenOrientation=”portrait”.
<application
…
android:screenOrientation=”portrait”
…
</activity>…</activity>
</application>
Step 3: Create a new folder anim under res folder
Here we will include two XML files representing our two transitional animations. Navigate to the app > res > anim > to_middle.xml and add the below code to that file. Below is the code for the to_middle.xml file.
XML
<? xml version = "1.0" encoding = "utf-8" ?> < scale xmlns:android = "http://schemas.android.com/apk/res/android" android:fromXScale = "1.0" android:toXScale = "0.0" android:pivotX = "50%" android:fromYScale = "1.0" android:toYScale = "1.0" android:pivotY = "50%" android:duration = "250" /> |
Now, Navigate to the app > res > anim > from_middle.xml and add the below code to that file. Below is the code for the from_middle.xml file.
XML
<? xml version = "1.0" encoding = "utf-8" ?> < scale xmlns:android = "http://schemas.android.com/apk/res/android" android:fromXScale = "0.0" android:toXScale = "1.0" android:pivotX = "50%" android:fromYScale = "1.0" android:toYScale = "1.0" android:pivotY = "50%" android:duration = "250" /> |
Step 4: Set any image(card front) object in the layout
Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file.
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:tools = "http://schemas.android.com/tools" android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = ".MainActivity" > < LinearLayout android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:gravity = "center" android:orientation = "vertical" app:layout_constraintBottom_toBottomOf = "parent" app:layout_constraintEnd_toEndOf = "parent" app:layout_constraintStart_toStartOf = "parent" > < TextView android:id = "@+id/textView1" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_margin = "10dip" android:text = "Simulate a 3D Flip" android:textColor = "#000" android:textSize = "26sp" android:textStyle = "bold" /> < ImageView android:id = "@+id/imageView1" android:layout_width = "wrap_content" android:layout_height = "300dp" android:layout_margin = "10dp" android:gravity = "center" android:src = "@drawable/card_front" /> < Button android:id = "@+id/button1" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_margin = "10dip" android:padding = "10dip" android:text = "Hit Me!" /> </ LinearLayout > </ androidx.constraintlayout.widget.ConstraintLayout > |
Step 5: Working with the MainActivity.kt file
Go to the MainActivity.kt file and refer to the following code. Below is the code for the MainActivity.kt file. Comments are added inside the code to understand the code in more detail.
Kotlin
import android.os.Bundle import android.view.animation.Animation import android.view.animation.AnimationUtils import android.widget.Button import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity(), Animation.AnimationListener { private lateinit var animation1: Animation private lateinit var animation2: Animation private var isFrontOfCardShowing = true private lateinit var image: ImageView private lateinit var clickBtn: Button override fun onCreate(savedInstanceState: Bundle?) { super .onCreate(savedInstanceState) setContentView(R.layout.activity_main) // apply animation from to_middle animation1 = AnimationUtils.loadAnimation( this , R.anim.to_middle) animation1.setAnimationListener( this ) // apply animation from to_middle animation2 = AnimationUtils.loadAnimation( this , R.anim.from_middle) animation2.setAnimationListener( this ) clickBtn = findViewById(R.id.button1) image = findViewById(R.id.imageView1) clickBtn.setOnClickListener { it.isEnabled = false // stop animation image.clearAnimation() image.animation = animation1 // start the animation image.startAnimation(animation1) } } override fun onAnimationEnd(animation: Animation) { if (animation === animation1) { // check whether the front of the card is showing if (isFrontOfCardShowing) { // set image from card_front to card_back image.setImageResource(R.drawable.card_back) } else { // set image from card_back to card_front image.setImageResource(R.drawable.card_front) } // stop the animation of the ImageView image.clearAnimation() image.animation = animation2 // allow fine-grained control // over the start time and invalidation image.startAnimation(animation2) } else { isFrontOfCardShowing = !isFrontOfCardShowing clickBtn.isEnabled = true } } override fun onAnimationRepeat(animation: Animation?) { // TODO Auto-generated method stub } override fun onAnimationStart(animation: Animation?) { // TODO Auto-generated method stub } } |
Now, run the app
Output:
Source Code: Click Here
Contact Us