Kotlin is the official programming language for Android apps development. In this tutorial, we’ll be discussing TextViews in Android applications using Kotlin programming. We’ll create and change TextViews code in Kotlin programming.
Android TextView Overview
Android TextView is a subclass of the View class. The View class typically occupy our window. TextView is used to display text on the screen. We can do a lot of fancy things using TextView.
Let’s start with a fresh project in Android Studio.
Create a new project and make sure you’ve enabled Kotlin in the setup wizard.
Creating TextView in XML Layout
TextView is created in an xml layout in the following manner.
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
The four attributes defined above are the core attributes of the TextView widget.
- The
id
property is used to set a unique identifier. It’s set as@+id/
followed by the name you assign. The same name would be used to retrieve the TextView property in our Kotlin Activity class. - The text property is used to set the string text to be displayed in the TextView.
- As it is evident from the names itself, layout_width and layout_height are used to set the boundaries of the TextView. The wrap_content means wrapping the width, height to the length of the text. The match_parent means the TextView matches the width/height of the enclosed parent view. We can also set hardcoded values in dp (device independent pixels).
Clean Code Tips: Instead of hardcoding the string, define it inside the strings.xml
and set the text in the layout as follows.
android:text="@string/app_name"
Let’s apply some attributes over the TextView in XML.
TextView XML Attributes
Let’s give you a quick tour of some of the popular attributes of TextView widget.
android:textSize
: sets the size of the TextView. It’s recommended to use sp instead of dp. The sp stands for scale independent pixels and scales the font. Example: 16sp.- The
android:textColor
is used to set a color for the text. Typically it is of the format #rgb, #rrggbb, #aarrggbb. - The
android:background
attribute is used to set the background color of the TextView. - The
android:textStyle
is used to set the style among bold, italic, and normal. If you want to set bold and italic, use android:textStyle = “bold|italic”. - The
android:textAppearance
attribute is used to set the style on a TextView, which includes its own color, font, and size. We can create custom styles in thestyles.xml
file. android:visibility
is used to set the visibililty of the text, possible values arevisible
,invisible
, andgone
. Thegone
makes the textview invisible and removes it from the current position in the layout.- The
android:ellipsize
is used to handle situations when the length of the text exceeds the limit. - The
end
adds dots when the text reaches the limit width of the TextView. Thestart
adds the dots at the beginning. Themarquee
is used to make the text continously slide left and right to show the full text. - The
android:onClick
is the method name in the Kotlin Activity class that’ll be invoked on TextView click. We need to ensure android:clickable is set to true for this attribute. android:typeface
is used to set the typeface of the text.android:drawableLeft
is used to set a drawable/mipmap image or vector asset besides the TextView.- The
android:gravity
is used to set the position of the text relative to its dimensions. android:layout_margin
is used to set the spacing of the TextView from the other views present in the layout. The layout_marginLeft, layout_marginRight, layout_marginTop, layout_marginBottom are used for setting margins on the individiual sides.- The
android:padding
is used to add spacing inside the four sides of the TextView. The possible values are paddingLeft, paddingRight, paddingTop, and paddingBottom.
.
Let’s use the xml attributes on a TextView in our layout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:id="@+id/linearLayout"
android:orientation="vertical"
tools:context="net.androidly.androidtextviewkotlin.MainActivity">
<TextView
android:id="@+id/textViewEllipsize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/long_string"
android:textSize="18sp" />
<TextView
android:id="@+id/textViewClickMe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:background="@color/colorPrimaryDark"
android:padding="@android:dimen/app_icon_size"
android:shadowColor="@android:color/black"
android:text="TextView Click Me" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android TextView Color"
android:textAllCaps="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#234568"
android:textStyle="bold|italic" />
<TextView
android:id="@+id/textViewOpacity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:drawableLeft="@mipmap/ic_launcher"
android:drawablePadding="16dp"
android:gravity="center"
android:text="Android TextView Opacity is 50 percent"
android:textColor="#50234568"
android:textSize="14sp"
android:typeface="serif" />
</LinearLayout>
Note: We’ve replaced the ConstraintLayout with a LinearLayout to make things easier.

Notice the opacity in the last TextView
For more info on XML attributes for Android TextView, visit the Google docs attached at the end of this page or JournalDev Android TextView tutorial.
In the following section, we’ll create TextView programmatically using Kotlin and set Kotlin functions, properties, and use lambda functions over the TextView.
Creating Android TextView using Kotlin
We can get the TextView in our MainActivity.kt Kotlin class using findViewById
.
The findViewById
is used to get a view from the XML in the Activity class using the id specified. It works like a dictionary – key/value pair.
package net.androidly.androidtextviewkotlin
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.TextView
class MainActivity : AppCompatActivity() {
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var textView = findViewById<textview>(R.id.textView)
//text property is equivalent to getText() or setText() in Java.
Log.d(TAG,"TextView text is ${textView.text}") //Logs TextView text is Android TextView Color
//setting the text.
textView.text = "Text changed"
//Setting the text from the strings.xml file.
textView.text = resources.getString(R.string.app_name)
}
}
Code Explanation:
- MainActivity Kotlin class extends AppCompatActivity.
- We’ve created the textView property by using
findViewById
. Though from Android API > 24 you can ignore specifying the type explicitly. - The text property is used as getter/setter on the TextView. It returns a CharSequence.
${textView.text}
implcitily converts the CharSequence to a String.- The
text
property in Kotlin is equivalent togetText()
andsetText(String)
in Java. - To set the string from the strings.xml file, we call
resources.getString(R.string.
. The resources property is equivalent to) getResources()
from Java.
Handling Null Values in TextView Kotlin Code
Kotlin has a very safe way to deal with null values. Optional Types act as a wrapper over the current type. They need to be safely unwrapped to use non-null values, thus enabling null safety in our Kotlin code.
Let’s look at how the above app behaves when the textView is null.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var textView = findViewById<textview>(R.id.textView)
textView.text = null
Log.d(TAG, "TextView text is ${textView.text}") // Logs TextView text is
textView = null
Log.d(TAG, "TextView text is ${textView.text}") //compilation error. Add safe call.
}
So when the text is null, the compiler ignores it.
When the textView is null, we need to add a safe call to unwrap the textView. This way Kotlin automatically gives us null safety.
What if the textView is null at runtime?
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//we've set a random id available from the autocomplete just to set textView to null at runtime.
var textView = findViewById<textview>(R.id.ALT)
Log.d(TAG, "TextView text is ${textView.text}")
}
It will throw error message as IllegalStateException. TextView cannot be null.
.
So let’s set the TextView properties as Optional in the declaration.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val otherTextView: TextView? = findViewById(R.id.textViewOpacity)
otherTextView?.text = null
Log.d(TAG, "TextView displays ${otherTextView?.text ?: "NA"}")
}
We’ve set otherTextView to the type TextView
.
So calling anything over the TextView would require a safe call.
What if the text is null? What do we display instead?
We use the elvis operator ?:
from Kotlin for null safety.
In the above code, NA gets displayed if otherTextView?.text
is null.
The safe call can be replaced by a let
lambda expression too.
Kotlin Android Extensions
Thanks to apply plugin: 'kotlin-android-extensions'
in our build.gradle
file, we can directly bind views from the layout in our Kotlin activity class.
Add the following import statement in your MainActivity.kt class.
import kotlinx.android.synthetic.main.activity_main.*
Now you can use the TextView properties directly without using findViewById.
Android TextView Kotlin onClick Listener
package net.androidly.androidtextviewkotlin
import android.graphics.Color
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v4.content.ContextCompat
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//set textView to clickable
textView.isClickable = true
textView.setOnClickListener{ textView.text = resources.getString(R.string.app_name) }
textViewClickMe.setOnClickListener { textViewClickMe.setTextColor(Color.WHITE) }
textViewEllipsize.ellipsize = TextUtils.TruncateAt.MARQUEE
textViewEllipsize.setHorizontallyScrolling(true)
textViewEllipsize.marqueeRepeatLimit = -1
textViewEllipsize.isSelected = true
val mipMapDrawable = ContextCompat.getDrawable(this, R.mipmap.ic_launcher)
textViewOpacity.setCompoundDrawablesWithIntrinsicBounds(mipMapDrawable,null,mipMapDrawable,null)
}
}
In the above code, for the setOnClickListener
we use lambda expressions from Kotlin. It makes the code shorter and easier to read than Java.
To make the textViewEllipsize
slide, set it to MARQUEE. To make it loop continuously, we’ve set marqueeRepeatLimit to -1.
The mipMapDrawable
is of the type Drawable and setCompoundDrawablesWithIntrinsicBounds()
is the equivalent of android:drawablePadding
.
The app output is shown in the following GIF.
Android TextView extension functions
We can create Kotlin extension functions on a TextView to add our custom functions and properties.
The below extension function creates a consistent property for currentTextColor
property and setTextColor()
function.
Add the following code outside the class.
var TextView.textColor: Int
get() = currentTextColor
set(v) = setTextColor(v)
We can then set the color on our TextView using the textColor
property.
textViewOpacity.textColor = ContextCompat.getColor(this, R.color.colorPrimaryDark)
Android TextView “with” expression
Instead of using redundant lines where we set the attributes on the same TextView property like this:
textViewEllipsize.ellipsize = TextUtils.TruncateAt.MARQUEE
textViewEllipsize.setHorizontallyScrolling(true)
textViewEllipsize.marqueeRepeatLimit = -1
textViewEllipsize.isSelected = true
textViewEllipsize.setOnClickListener { println("So many calls to the same TextView") }
We can make it better using the with
expression.
with(textViewEllipsize)
{
ellipsize = TextUtils.TruncateAt.MARQUEE
setHorizontallyScrolling(true)
marqueeRepeatLimit = -1
isSelected = true
setOnClickListener { println("WOW. AWESOME.") }
}
Creating a TextView Programmatically in Kotlin
Below, we’ve created two TextViews programmatically. We’ve set a custom font from the assets folder and set underline on one of the TextViews. Also, we’ve set the string in the form of HTML.
The assets directory is created under src | main folder and is used to hold the TTF files for the custom fonts.
package net.androidly.androidtextviewkotlin
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Typeface
import android.os.Build
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v4.content.ContextCompat
import android.text.Html
import android.text.TextUtils
import android.view.Gravity
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
val TAG = "MainActivity"
lateinit var programmaticTextView : TextView
var optionalTextView : TextView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
programmaticTextView = TextView(this)
with(programmaticTextView)
{
text = "I'm Created Programmatically. Kotlin makes life simple"
textSize = 20f
textColor = Color.parseColor("#1F2135")
typeface = Typeface.DEFAULT_BOLD
isClickable = true
setOnClickListener { println("I contain the string: $text") }
}
linearLayout.addView(programmaticTextView)
optionalTextView = TextView(this)
optionalTextView.let { with(optionalTextView!!)
{
text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
"${Html.fromHtml("
<h4>this is underlined text</h4>
Body goes here",Html.FROM_HTML_MODE_LEGACY)}"
} else {
@Suppress("DEPRECATION")
"${Html.fromHtml("this is <u>underlined</u> text")}"
}
typeface = Typeface.createFromAsset(assets, "Pacifico.ttf")
textSize = 20f
gravity = Gravity.CENTER
paintFlags = Paint.UNDERLINE_TEXT_FLAG
} }
linearLayout.addView(optionalTextView)
}
}
var TextView.textColor: Int
get() = currentTextColor
set(v) = setTextColor(v)
Kotlin properties are required to be initialized there itself. If it’s not possible, we can set a lateinit
modifier to the property.
By default, when the textView is created programmatically, its width is match_parent
and height is wrap_content
.
The paintFlags
is used to add an underline to the string.
The output with the above TextViews added into the layout programmatically is shown in the following image.
Using Spannable Strings
Spannable Strings are useful when we have to set different styles on different substrings of the TextView.
val string = "this is normal, this is underlined"
val firstWord = string.substringBefore(",")
val secondWord = string.substringAfterLast(",")
val redColor = ForegroundColorSpan(
ContextCompat.getColor(this,android.R.color.holo_red_dark))
val ssb = SpannableStringBuilder(firstWord)
ssb.setSpan(
redColor, // the span to add
0, // the start of the span (inclusive)
ssb.length, // the end of the span (exclusive)
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
ssb.append(" ")
val underlineSpan = UnderlineSpan()
ssb.append(secondWord)
ssb.setSpan(
underlineSpan,
ssb.length - secondWord.length,
ssb.length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
optionalTextView = TextView(this)
optionalTextView.let { with(optionalTextView!!)
{
text = ssb
typeface = Typeface.createFromAsset(assets, "Pacifico.ttf")
textSize = 20f
gravity = Gravity.CENTER
} }
linearLayout.addView(optionalTextView)
Output:
This brings an end to the comprehensive tutorial on Android TextViews using Kotlin programming.