Android Kotlin - Create CardView and TextView programatically

 My first app Maths Challenger written in Kotlin uses CardView and TextView on its landing activity and on subsequent activities. One of the options I had was to add CardView and TextView using XML statically. But I choose to add them programmatically as it gives an easy, flexible and scalable way to add new cards/text when required or to update any attributes without much effort by changing them in one place. Below is the screenshot of the landing activity.






activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:id="@+id/addScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#dde0fc">

<LinearLayout
android:id="@+id/mainLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:orientation="vertical" />

</ScrollView>

In the above XML code, you can see that I have just added a LinearLayout under the ScrollView. I have done this to just give me some framework to hold various CardView and TextView that I would add now (one for each operation).

First, I have created a base class called MathsChallengerBase which extends the AppCompactActivity. This is important as I want to use the power of object-oriented language such as Kotlin. This class would hold all the common stuff that I want child classes to inherit (I have not shown all the child classes in this blog). This class renderLandingCard is of special importance from the perspective of this blog. Here you can see that I have created a LinearLayout cardLinearLayoutVert with a VERTICAL orientation.  This layout would be used to hold anything that goes inside the CardView. It's important to appreciate that I have not created a CardView inside this function, instead, I am just setting the attributes for the cardView that is passed in the arguments to renderLandingCard. I am doing this because I want different actions to be taken when different cards are clicked (see setOnClickListener under MainActivity.kt).  Now, based on the cardNameText I am changing the background colour for the card. Finally, addTextView is called to add the name of the card (i.e. Addition, Subtraction, etc) and the function addView called to add the views.
Note: I have just shown a part of MathsChallengerBase.kt class below as the rest of the code under this class is not relevant to this blog. I am planning to cover different aspects of this app in my upcoming blog.

MathsChallengerBase.kt
open class MathsChallengerBase : AppCompatActivity() {
    // Text colours
    val landingCardTextColor: String = "#FFFFFF"
    val medalCardTextColor: String = "#FFFFFF"
    val greyTextColor: String = "#8b929a"
    // Colours for various Landing Cards
    val addLandingCardColor: String = "#98a3f7"
    val subLandingCardColor: String = "#8b97f5"
    val mulLandingCardColor: String = "#7f8cf4"
    val divLandingCardColor: String = "#7180f3"
    val algLandingCardColor: String = "#6474f2"
    val medLandingCardColor: String = "#596af1"
    // Colours for various activities
    val mainActivityBackColor: String = "#dde0fc"
    val addActivityBackColor: String = "#dde0fc"
    val subActivityBackColor: String = "#dde0fc"
    val mulActivityBackColor: String = "#dde0fc"
    val divActivityBackColor: String = "#dde0fc"
    val algActivityBackColor: String = "#dde0fc"
    val medalActivityBackColor: String = "#dde0fc"
/****************************************************************
Function to add text view programatically
****************************************************************/
fun addTextView(
repLinearLayout: LinearLayout,
text: String,
textSize: Float,
gravity: Int,
typeFace1: Typeface,
typeFace2: Int,
textColor: String,
leftPad: Int,
topPad: Int,
rightPad: Int,
bottomPad: Int
) {
val textView = TextView(this)
textView.text = text
textView.textSize = textSize
textView.gravity = gravity
textView.setTypeface(typeFace1, typeFace2)
textView.setTextColor(Color.parseColor(textColor))
textView.setPadding(leftPad, topPad, rightPad, bottomPad)

repLinearLayout.addView(textView)
}

/****************************************************************
Function to render card for the landing page.
****************************************************************/
@SuppressLint("Range")
@RequiresApi(Build.VERSION_CODES.M)
fun renderLandingCard(
mainLinearLayout: LinearLayout,
cardView: CardView,
cardNameText: String,
textColor: String
) {

val cardLinearLayoutVert = LinearLayout(this)
cardLinearLayoutVert.orientation = LinearLayout.VERTICAL

val params = RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
params.setMargins(15, 20, 15, 0)
cardView.radius = 20f
cardView.setContentPadding(0, 0, 5, 0)
cardView.layoutParams = params
cardView.cardElevation = 30f
cardView.isClickable = true

if (cardNameText == "Addition")
cardView.setCardBackgroundColor(Color.parseColor(addLandingCardColor))
if (cardNameText == "Subtraction")
cardView.setCardBackgroundColor(Color.parseColor(subLandingCardColor))
if (cardNameText == "Multiplication")
cardView.setCardBackgroundColor(Color.parseColor(mulLandingCardColor))
if (cardNameText == "Division")
cardView.setCardBackgroundColor(Color.parseColor(divLandingCardColor))
if (cardNameText == "Algebra")
cardView.setCardBackgroundColor(Color.parseColor(algLandingCardColor))

// Card Name
addTextView(
cardLinearLayoutVert, cardNameText, 30F
            Gravity.CENTER, Typeface.DEFAULT_BOLD,
Typeface.NORMAL, textColor, 0, 0, 0, 20
)

cardView.addView(cardLinearLayoutVert)

mainLinearLayout.addView(cardView)

}
}
Next, lets look at the MainActivity which extends MathsChallengerBase. Here you can see that I have first got the handle to mainLinearLayout from the xml and called it mainLinearLayout. I am then adding the TextView to set various texts like name of the app and information to the user. Finally, I am creating various CardView and calling the function renderLandingCard to render them.
MainActivity.kt
class MainActivity : MathsChallengerBase() {


@RequiresApi(Build.VERSION_CODES.M)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)


val mainLinearLayout = findViewById(R.id.mainLinearLayout) as LinearLayout
mainLinearLayout.setBackgroundColor(Color.parseColor(mainActivityBackColor))

addTextView(
mainLinearLayout, "Maths Challenger", 40F
            Gravity.CENTER, Typeface.DEFAULT_BOLD,
Typeface.NORMAL, "#000000", 0, 10, 0, 40
)

addTextView(
mainLinearLayout, "Select your challenge", 30F
            Gravity.CENTER, Typeface.DEFAULT_BOLD,
Typeface.NORMAL, greyTextColor, 0, 10, 0, 40
)

val addCardId = CardView(this)
renderLandingCard(mainLinearLayout,addCardId, "Addition",landingCardTextColor)
addCardId.setOnClickListener{
startActivity(Intent(this, Addition::class.java))
}

val subCardId = CardView(this)
renderLandingCard(mainLinearLayout,subCardId,"Subtraction",landingCardTextColor)
subCardId.setOnClickListener{
startActivity(Intent(this, Subtraction::class.java))
}


val mulCardId = CardView(this)
renderLandingCard(mainLinearLayout,mulCardId,"Multiplication",landingCardTextColor)
mulCardId.setOnClickListener{
startActivity(Intent(this, Multiplication::class.java))
}


val divCardId = CardView(this)
renderLandingCard(mainLinearLayout,divCardId,"Division",landingCardTextColor)
divCardId.setOnClickListener{
startActivity(Intent(this, Division::class.java))
}

val algCardId = CardView(this)
renderLandingCard(mainLinearLayout,algCardId,"Algebra",landingCardTextColor)
algCardId.setOnClickListener{
startActivity(Intent(this, Algebra::class.java))
}

val medalCardId = CardView(this)
renderMedalCard(mainLinearLayout,medalCardId,"My Medals",medalCardTextColor)
medalCardId.setOnClickListener{
startActivity(Intent(this, Medals::class.java))
}
}
}
Appriciate your patients and thanks for reading throug the end of this blog. If you want to know more about any other apsect of my first app Maths Challenger please comment on this blog and I would be more than happy to help where I can. If you want to find out my other apps please visit Play Store

Comments