Creating Custom Views In Android

1.1. Default views

The Android framework provides several default views. The base class a view is the View. Views are responsible for measuring and drawing themselves and their child elements (in case of a ViewGroup). Views are also responsible for saving their UI state and handling touch events. Developers can also create custom views and use them in their applications.

It is possible to create custom views by:

  1. Compound views — combining views with a default wiring
  2. Custom views — creating your own views

2.a. by extending an existing view, e.g. Button

2.b. by extending the View class

The following image shows the default view hierarchy of Android.

1.2. Create a new view

Imagine that you have an application that should analyze storage data and give you information with a chart.

1.For first we should create a new class which will extend from ViewGroup, in my case I will extend my view from LinearLayout

class CustomChart @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {

var view: View = LayoutInflater.from(context).inflate(R.layout.custom_chart_view, this, false)

init {
addView(view)
drawChart()
}


fun drawChart(i1: Float = 30f, i2: Float = 20F, i3: Float = 20F, i4: Float = 30F) {
val first: LinearLayout = view.findViewById(R.id.first)
val second: LinearLayout = view.findViewById(R.id.second)
val third: LinearLayout = view.findViewById(R.id.third)
val fourth: LinearLayout = view.findViewById(R.id.fourth)

first.layoutParams = getLayoutParams(i1)
second.layoutParams = getLayoutParams(i2)
third.layoutParams = getLayoutParams(i3)
fourth.layoutParams = getLayoutParams(i4)
}

private fun getLayoutParams(weight: Float): LayoutParams {
return LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT, weight)
}
}

I create a very simple example for showing you the main idea of creating a custom view and for that I use a static number of layouts but if you want you can change some part of my code and you can use as many layouts as you want.

2.For Second we should create a new layout file which will the view which user will see.There are some cases when you can not create a xml file but i prefer to have my xml where i can give my desing as how as i want.

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
app:cardCornerRadius="71dp"
card_view:cardElevation="0dp"
card_view:contentPadding="0dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="100"
android:orientation="horizontal">

<LinearLayout
android:id="@+id/first"
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="@drawable/security_chart_background"
android:orientation="horizontal"
tools:ignore="Suspicious0dp" />

<LinearLayout
android:id="@+id/second"
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="@drawable/battery_chart_background"
android:orientation="horizontal"
tools:ignore="Suspicious0dp" />

<LinearLayout
android:id="@+id/third"
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="@drawable/cache_chart_background"
android:orientation="horizontal"
tools:ignore="Suspicious0dp" />

<LinearLayout
android:id="@+id/fourth"
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="@drawable/cool_chart_background"
android:orientation="horizontal"
tools:ignore="Suspicious0dp" />
</LinearLayout>

</androidx.cardview.widget.CardView>

Now we have our view which we can use as other Views or ViewGroups for using it you should only write the name of your View in the XML file. Now we will use our CustomChart in Main Activity and gave him random numbers and it will automatically draw our chart.

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
generateRandomNumbers()

window.statusBarColor = getColor(R.color.statusBar)
}

private fun generateRandomNumbers() {
val shakeAnimation = AnimationUtils.loadAnimation(this, R.anim.shake)
settings.setOnClickListener {
val i1 = (0..20).random() + 10
val i2 = (0..20).random() + 10
val i3 = (0..20).random() + 10
val i4 = (100 - i1 - i2 - i3)
chart.drawChart(i1.toFloat(), i2.toFloat(), i3.toFloat(), i4.toFloat())
cacheContainer.startAnimation(shakeAnimation)
coolContainer.startAnimation(shakeAnimation)
securityContainer.startAnimation(shakeAnimation)
batteryContainer.startAnimation(shakeAnimation)

}
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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"
android:fillViewport="true">


<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
tools:context=".MainActivity">

<com.example.cleaner.CustomChart
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="17dp"
app:layout_constraintTop_toBottomOf="@id/space" />

</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

Here You can the final result

https://youtu.be/7Bill6vDitw

For more information, you can visit my project in git. Thank you for your attention. I hope this article was helpful to you.

--

--

--

Hi I am Arsen I am 23 old Android Developer From Armenia Trying to do my best for improving Android Community.

Love podcasts or audiobooks? Learn on the go with our new app.

Memory Management In Android

Android — RecyclerView Swipe to Edit/Delete

Animation on LazyColumn the RecyclerView Equivalent

Network Data Transfer Using Volley Library— Android

Dagger for Android: A Beginner’s Guide to Multibindings

How to use dagger with retrofit and get rid of initialization!

Android Interview Questions: 2020

Use Android Studio BottomSheet with kotlin.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Arsen Asatryan

Arsen Asatryan

Hi I am Arsen I am 23 old Android Developer From Armenia Trying to do my best for improving Android Community.

More from Medium

Some Best Practices for Android App Architecture

How to create a simple coroutine in Kotlin, Android

Android ViewModel and ViewModel Factory

Android Biometric API Findings