Recently i have seen many people building fidget spinners apps so i decided to take some time and build my own fidget spinner app and post it online.
Note: This application is built completely in Kotlin and was done using Android studio 3.0 (Alpha). this is not a Kotlin tutorial, for those of you who do not know how to setup Kotlin for android development, please see HERE.
The goal of this tutorial is very straight forward, create an application with an ImageView that rotates and vibrates the phone on press.
Lets start with the XML
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout android:id="@+id/container" 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="com.josiassena.fidgetspinner.MainActivity"> <android.support.v7.widget.AppCompatImageView android:id="@+id/ivFidget" android:layout_width="300dp" android:layout_height="300dp" app:srcCompat="@drawable/fidget_spinner_yellow" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent"/> </android.support.constraint.ConstraintLayout>
The xml is pretty straight forward, theres a ConstraintLayout with a single image view inside of it.
Now lets take a look at the only activity in the application, the MainActivity.
First we want to add an onTouchListener to the ivFidget. This is what will notify us when the spinner has been touched. In order to do this we do the following on the onCreate of the activity.
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ivFidget.setOnTouchListener { v, event -> } } }
There are two events we want to listen to. When the user presses the image and when they let go. In order to do this we do:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ivFidget.setOnTouchListener { v, event -> when (event.action) { KeyEvent.ACTION_DOWN -> { } KeyEvent.ACTION_UP -> { } } true } } }
First things first, lets vibrate the device when the spinner is touched, and lets stop vibrating when the spinner is released.
class MainActivity : AppCompatActivity() { lateinit var vibrator: Vibrator // get ready to init the vibrator override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Initialize the vibrator vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator ivFidget.setOnTouchListener { v, event -> when (event.action) { KeyEvent.ACTION_DOWN -> { startVibration() } KeyEvent.ACTION_UP -> { stopVibration() } } true } } private fun startVibration() { // if the device can vibrate, then lets vibrate! if (vibrator.hasVibrator()) { vibrator.vibrate(500000) } } private fun stopVibration() { // If the device can vibrate then lets stop all of its vibrations if (vibrator.hasVibrator()) { vibrator.cancel() } } }
The last and final piece of this entire application is to spin the spinner using a RotateAnimation.
class MainActivity : AppCompatActivity() { lateinit var vibrator: Vibrator override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator ivFidget.setOnTouchListener { v, event -> when (event.action) { KeyEvent.ACTION_DOWN -> { ivFidget.startAnimation(getSpinAnimation()) startVibration() } KeyEvent.ACTION_UP -> { ivFidget.clearAnimation() stopVibration() } } true } } private fun getSpinAnimation(): RotateAnimation { val spin = RotateAnimation(0f, 1000000f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f) spin.duration = Math.abs(Animation.INFINITE.toLong()) // must be positive spin.repeatCount = Animation.INFINITE spin.interpolator = LinearOutSlowInInterpolator() spin.fillAfter = false return spin } private fun startVibration() { if (vibrator.hasVibrator()) { vibrator.vibrate(500000) } } private fun stopVibration() { if (vibrator.hasVibrator()) { vibrator.cancel() } } }
Thats it. Run the app and when the image view is clicked the image will spin and vibrate the device. For the full source code of this please visit HERE.
This is all for this post, hope you guys enjoy it. In the next post we will take a look on how to spin and move the spinner at the same time.
Until next time.