In this article, we will learn how to create an animated login screen for your app with step-by-step guidance. so let's start, follow bellow steps to make it.
Step 1: Create a new project with an empty activity. use kotlin as a programming language.
Step 2: Create two vector assets in a drawable folder for the user and password. give it the name userr.xml and password.xml
Step 3: Add your png file or photo for use as a profile photo
Step 4: Now create drawable resource files in the drawable folder, name it as below, and add codes in it as I provided below. also, add the main activity kotlin and xml codes as I have given below.
circle_shape.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#20ffffff" />
</shape>
gradient_background.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="0dp" />
<gradient
android:startColor="#7B97FD"
android:endColor="#0526C9"
android:type="linear"
android:angle="90"/>
</shape>
rounded_corners.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:topLeftRadius="50dp"
android:topRightRadius="50dp"
android:bottomLeftRadius="50dp"
android:bottomRightRadius="50dp" />
<solid android:color="#30FFFFFF" />
</shape>
rounded_corners_whitebg.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="10dp"/>
<solid android:color="#216EF3" />
</shape>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout</androidx.constraintlayout.widget.ConstraintLayout>
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:background="@drawable/gradient_background"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/relativeLayout2"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="30dp"
android:layout_marginTop="90dp"
android:layout_marginRight="30dp"
android:layout_marginBottom="200dp"
android:background="@drawable/rounded_corners"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:layout_gravity="center"
android:layout_marginTop="28dp"
android:background="@drawable/circle_shape"
android:src="@drawable/man_pro"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</ImageView>
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:drawableLeft="@drawable/userr"
android:drawablePadding="20dp"
android:hint="Username"
android:padding="20dp"
android:textColor="@color/white"
android:textColorHint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView"
app:layout_constraintVertical_bias="0.027" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/username"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:layout_marginTop="15dp"
android:drawableLeft="@drawable/password"
android:drawablePadding="20dp"
android:hint="Password"
android:padding="20dp"
android:textColor="@color/white"
android:textColorHint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/username"
app:layout_constraintVertical_bias="0.032" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:orientation="horizontal"
>
<CheckBox
android:id="@+id/checkBox"
android:textColor="@color/white"
android:textSize="12dp"
android:layout_marginLeft="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:textColorHint="@color/white"
android:hint="Remember me" />
<TextView
android:text="Forgot password?"
android:textColor="@color/white"
android:textSize="12dp"
android:layout_marginLeft="65dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<Button
android:id="@+id/login_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/username"
android:layout_marginTop="35dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:drawablePadding="20dp"
android:padding="10dp"
android:text="Login"
android:textAllCaps="false"
android:textColor="@color/white"
android:textSize="20dp"
android:textStyle="bold"
android:background="@drawable/rounded_corners_whitebg"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/password"
app:layout_constraintVertical_bias="0.065" />
</LinearLayout>
MainActivity.kt
import android.animation.ObjectAnimator
import android.annotation.SuppressLint}
import android.app.Activity
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.LinearLayout
class MainActivity : Activity(), View.OnTouchListener {
private var dX = 0f
private var dY = 0f
private var initialTouchX = 0f
private var initialTouchY = 0f
private var isCardAnimating = false
private lateinit var cardView: LinearLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
cardView = findViewById(R.id.relativeLayout2)
cardView.setOnTouchListener(this)
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouch(view: View, event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
// Save the initial touch position and the position of the view
initialTouchX = event.rawX
initialTouchY = event.rawY
dX = view.x - event.rawX
dY = view.y - event.rawY
}
MotionEvent.ACTION_MOVE -> {
// Calculate the new position of the view based on the touch position and the offset
val newX = event.rawX + dX
val newY = event.rawY + dY
// Calculate the amount of rotation based on the distance between the initial touch position and the current touch position
val rotationX = -(event.rawY - initialTouchY) / 2f
val rotationY = (event.rawX - initialTouchX) / 2f
// Set the new position and rotation of the view
view.animate()
.x(newX)
.y(newY)
.setDuration(0)
.start()
view.rotationX = rotationX
view.rotationY = rotationY
isCardAnimating = true
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
// Animate the view back to its original position and rotation
val animX = ObjectAnimator.ofFloat(view, View.X, initialTouchX + dX)
val animY = ObjectAnimator.ofFloat(view, View.Y, initialTouchY + dY)
val animRotationX = ObjectAnimator.ofFloat(view, View.ROTATION_X, 0f)
val animRotationY = ObjectAnimator.ofFloat(view, View.ROTATION_Y, 0f)
animX.duration = 500
animY.duration = 500
animRotationX.duration = 500
animRotationY.duration = 500
animX.interpolator = AccelerateDecelerateInterpolator()
animY.interpolator = AccelerateDecelerateInterpolator()
animRotationX.interpolator = AccelerateDecelerateInterpolator()
animRotationY.interpolator = AccelerateDecelerateInterpolator()
animX.start()
animY.start()
animRotationX.start()
animRotationY.start()
isCardAnimating = false
}
}
return true
}
override fun onBackPressed() {
if (isCardAnimating) {
// Block back button during card animation
return
}
super.onBackPressed()
}
All done. Now run your app.