I am designing a Feed in which I want the posts in the form of a Card which I implemented using design library of Google. I have created my layout but as the posts will be fetched dynamically therefore I wanted to dynamically create my layout in Kotlin. For that I created a function which will take Image,Title,Description as the parameters and will return a Card View Object.
To set the attributes in CardView I tried layoutParams but using it just crashed my app
val cardViewParam = cardView.layoutParams as CoordinatorLayout.LayoutParams
In this code I tried every layout type Linear,Relative,Coordinator and even ViewGroup but my app keeps on crashing every time.
This is my layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:layout_height="match_parent"
tools:context=".Home"
android:background="@color/DirtyWhite"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:tag="FEED">
//This is the card view which I want to create dynamically
<android.support.v7.widget.CardView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:elevation="50dp"
app:cardCornerRadius="10dp">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:clipToPadding="false">
<ImageView android:layout_width="match_parent"
android:layout_height="180dp"
android:src="@drawable/sample"
android:scaleType="centerCrop"
android:layout_marginTop="-10dp"
android:layout_marginStart="-10dp"
android:layout_marginEnd="-10dp"
android:layout_marginBottom="-10dp"
android:adjustViewBounds="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Base.TextAppearance.AppCompat.Title"
android:text="This is a part of Material Design."
android:ellipsize="end"
android:maxLines="1"
android:layout_marginTop="16dp"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/TextAppearance.AppCompat.Body2"
android:text="This is a part of Material Design. This is a part of Material Design. This is a part of Material Design. "
android:ellipsize="end"
android:textColor="@color/realGray"
android:maxLines="2"
android:layout_marginTop="8dp"
/>
<RelativeLayout android:layout_width="match_parent"
android:layout_marginTop="8dp"
android:layout_height="wrap_content">
<RatingBar android:layout_width="wrap_content" android:layout_height="wrap_content"
android:numStars="5"
android:rating="3"
android:isIndicator="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerInParent="true"
style="@style/Base.Widget.AppCompat.RatingBar.Small"/>
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/ic_favorite_border_black_24dp"
android:minHeight="30dp"
android:minWidth="30dp"
android:layout_marginRight="15dp"
android:layout_marginEnd="15dp"
/>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Order Now"
android:background="@drawable/rounded_card_button_small"
android:textColor="@color/DirtyWhite"
android:minHeight="0dp"
android:minWidth="0dp"
android:padding="5dp"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</ScrollView>
I tried this code to create layout dynamically: (NOTE: This code was made just to create basic Card excluding the Rating Bar and other Action Buttons)
fun createAdsPost(view: View, photo: ImageView, titleText: String, descText: String): CardView {
val cardView = CardView(view.context)
val cardViewParam = cardView.layoutParams as CoordinatorLayout.LayoutParams
cardView.layoutParams = cardViewParam
cardViewParam.width = LinearLayout.LayoutParams.MATCH_PARENT
cardViewParam.height = LinearLayout.LayoutParams.WRAP_CONTENT
cardViewParam.setMargins(dpToPx(5, view), dpToPx(5, view), dpToPx(5, view), dpToPx(5, view))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cardView.elevation = dpToPx(50, view).toFloat()
}
cardView.apply {
radius = dpToPx(10, view).toFloat()
this.layoutParams = cardViewParam
}
val linear1 = LinearLayout(view.context)
linear1.orientation = LinearLayout.VERTICAL
linear1.setPadding(dpToPx(10, view), dpToPx(10, view), dpToPx(10, view), dpToPx(10, view))
linear1.clipToPadding = false
val linear1Param = linear1.layoutParams as LinearLayout.LayoutParams
linear1Param.width = LinearLayout.LayoutParams.MATCH_PARENT
linear1Param.height = LinearLayout.LayoutParams.WRAP_CONTENT
linear1.layoutParams = linear1Param
photo.scaleType = ImageView.ScaleType.CENTER_CROP
photo.adjustViewBounds = true
val photoParams = photo.layoutParams as LinearLayout.LayoutParams
photoParams.apply {
width = LinearLayout.LayoutParams.MATCH_PARENT
height = dpToPx(180, view)
topMargin = dpToPx(-10, view)
bottomMargin = dpToPx(-10, view)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
photoParams.marginStart = dpToPx(-10, view)
photoParams.marginEnd = dpToPx(-10, view)
}
linear1.addView(photo)
val title = TextView(view.context)
title.apply {
ellipsize = TextUtils.TruncateAt.END
maxLines = 1
text = titleText
}
val titleTextParams = title.layoutParams as LinearLayout.LayoutParams
titleTextParams.apply {
width = LinearLayout.LayoutParams.MATCH_PARENT
height = LinearLayout.LayoutParams.WRAP_CONTENT
topMargin = dpToPx(16, view)
}
linear1.addView(title)
val desc = TextView(view.context)
desc.apply {
ellipsize = TextUtils.TruncateAt.END
maxLines = 2
text = descText
setTextColor(Color.parseColor("#626567"))
}
val descTextParams = desc.layoutParams as LinearLayout.LayoutParams
descTextParams.apply {
width = LinearLayout.LayoutParams.MATCH_PARENT
height = LinearLayout.LayoutParams.WRAP_CONTENT
topMargin = dpToPx(8, view)
}
linear1.addView(desc)
cardView.addView(linear1)
return cardView
}
When I am using these codes my app is crashing. I tried to debug my codes and came to know that the first error is in the layoutParams
of CardView.
In short, I want to know how can I set attributes in the Card View
Also, Please Tell is this the only way to create dynamic layout or there is a more efficient way. I am new in Android Developing.
I would like to suggest one thing, if your requirement is to create view dynamically then you just try one thing that is :
1) Make a separate layout file for your dymanic view 2) Inflate that layout using :
val layoutInflater = getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
layoutInflater!!.inflate(R.layout.your_layout_file)
3) Now you will have view, then you just have to access the layour views using something like :
view.findViewById(you view id)
4) now you will be able to create and access your view dynamically easily
Note:
getContent() : will come according to your usage on fragment or in activity, so need to change it accordingly
same as inflate method, use parameter according to your requirement