I'm trying to use the latest version of the FontAwesome typeface for a TextView in a LinearLayout that I created programmatically, but instead a box is shown containing a cross. I tried both FontManager.getTypeface(activity!!.baseContext, FontManager.FONTAWESOME) and FontManager.getTypeface(activity!!.applicationContext, FontManager.FONTAWESOME) but neither of these worked. I'm even using the latest .otf file provided by FontAwesone. I really don't understand what I've done wrong, because I followed all the instructions on the FontAwesome website. Is there a problem because the layout is created dynamically or something else?
FontManager object
object FontManager {
private const val ROOT = "fonts/"
internal const val FONTAWESOME = ROOT + "fontawesome5-free-regular.otf"
internal fun getTypeface(context: Context, font: String): Typeface {
return Typeface.createFromAsset(context.assets, font)
}
}
Fragment class
class MyFragment : androidx.fragment.app.Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val mainRelativeLayout = RelativeLayout(activity)
// Layout Parameters for relative layout items
val rlpCVPrimary = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT)
val rlpTVPrimaryIcon = RelativeLayout.LayoutParams(LinearLayout.LayoutParams
.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT)
val rlpTVPrimaryText = RelativeLayout.LayoutParams(LinearLayout.LayoutParams
.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT)
val rlpTVTitle = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT)
val rlpCVSecondary = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT)
val rlpTVSecondaryIcon = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT)
val rlpTVSecondaryText = RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT)
// Accessing FontAwesome font
val iconFont = FontManager.getTypeface(activity!!.applicationContext, FontManager.FONTAWESOME)
//
val r = context!!.resources
val fourDp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4f, r.displayMetrics).toInt()
val tenDp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10f, r.displayMetrics).toInt()
val thirtyDp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30f, r.displayMetrics).toInt()
// Creating RelativeLayouts for root layout
val cvRLPrimary = RelativeLayout(context)
val cvRLSecondary = RelativeLayout(context)
// Creating CardViews
val cvPrimary = context?.let { CardView(it) }
when {
cvPrimary != null -> {
cvPrimary.radius = fourDp.toFloat()
cvPrimary.setContentPadding(tenDp,tenDp,tenDp,tenDp)
cvPrimary.useCompatPadding = true
cvPrimary.cardElevation = fourDp.toFloat()
cvPrimary.layoutParams = rlpCVPrimary
}
}
rlpCVPrimary.setMargins(0, 0, 0, thirtyDp)
val cvSecondary = context?.let { CardView(it) }
when {
cvSecondary != null -> {
cvSecondary.radius = fourDp.toFloat()
cvSecondary.setContentPadding(tenDp,tenDp,tenDp,tenDp)
cvSecondary.useCompatPadding = true
cvSecondary.cardElevation = fourDp.toFloat()
cvSecondary.layoutParams = rlpCVSecondary
}
}
rlpCVSecondary.setMargins(0, 0, 0, thirtyDp)
/*
* Creating Primary CardView items
*/
// 'tvPrimaryIcon' TextView
val tvPrimaryIcon = TextView(context)
tvPrimaryIcon.text = getString(R.string.fa_icon_sign_in)
tvPrimaryIcon.typeface = iconFont
tvPrimaryIcon.layoutParams = rlpCVPrimary
tvPrimaryIcon.setMargins(0, 0, tenDp, 0)
TextViewCompat.setTextAppearance(tvPrimaryIcon, android.R.style.TextAppearance_Medium)
// 'tvPrimaryText' TextView
val tvPrimaryText = TextView(context)
tvPrimaryText.text = getString(R.string
.primary_title)
TextViewCompat.setTextAppearance(tvPrimaryText, android.R.style.TextAppearance_Medium)
// 'tvTitle' TextView
val tvTitle = TextView(context)
tvTitle.text = getString(R.string.hello_world)
tvTitle.gravity = Gravity.CENTER
TextViewCompat.setTextAppearance(tvTitle, android.R.style.TextAppearance_Medium)
rlpTVTitle.setMargins(0, tenDp, 0, tenDp)
/*
* Creating Secondary CardView items
*/
// 'tvSecondaryIcon' TextView
val tvIconExit = TextView(context)
tvIconExit.text = getString(R.string.fa_icon_sign_out)
tvIconExit.typeface = iconFont
TextViewCompat.setTextAppearance(tvIconExit, android.R.style.TextAppearance_Medium)
rlpTVIconExit.setMargins(0, 0, tenDp, 0)
// 'tvSecondaryText' TextView
val tvSecondaryText = TextView(context)
tvSecondaryText.text = getString(R.string.secondary_title)
TextViewCompat.setTextAppearance(tvSecondaryText, android.R.style.TextAppearance_Medium)
// Set IDs for text views
mainRelativeLayout.id = View.generateViewId()
cvPrimary!!.id = View.generateViewId()
tvPrimaryIcon.id = View.generateViewId()
tvPrimaryText.id = View.generateViewId()
tvTitle.id = View.generateViewId()
cvSecondary!!.id = View.generateViewId()
tvSecondaryIcon.id = View.generateViewId()
tvSecondaryText.id = View.generateViewId()
// Set Layout Parameters for text views
tvPrimaryIcon.layoutParams = rlpTVPrimaryIcon
tvPrimaryText.layoutParams = rlpTVPrimaryText
tvTitle.layoutParams = rlpTVTitle
tvSecondaryIcon.layoutParams = rlpTVSecondaryIcon
tvSecondaryText.layoutParams = rlpTVSecondaryText
// Set RelativeLayout rules for views
rlpTVPrimaryText.addRule(RelativeLayout.END_OF, tvPrimaryIcon.id)
rlpTVTitle.addRule(RelativeLayout.BELOW, cvPrimary.id)
rlpCVSecondary.addRule(RelativeLayout.BELOW, tvTitle.id)
rlpTVSecondaryText.addRule(RelativeLayout.END_OF, tvSecondaryIcon.id)
// Adding items to root layout
mainRelativeLayout.addView(cvPrimary)
cvPrimary.addView(cvRLPrimary)
cvRLPrimary.addView(tvPrimaryIcon)
cvRLPrimary.addView(tvPrimaryText)
mainRelativeLayout.addView(tvTitle)
mainRelativeLayout.addView(cvSecondary)
cvSecondary.addView(cvRLSecondary)
cvRLSecondary.addView(tvSecondaryIcon)
cvRLSecondary.addView(tvSecondaryText)
return mainRelativeLayout
}
}
Related
Expected outcome:
I want to show only ImageView and TextView that corresponds to the current position e.g if I have
val icons = craftingExpandableList[position].requiredList?.icon
val amounts = craftingExpandableList[position].requiredList?.amount
I want to show in RecyclerView only icons and amounts from current position, not all existing icons and amounts.
Current outcome:
I've added 2 items to my list. The problem is with the expandable list. It has values and images from both items that I've added previously. I suppose, that the problem is with for loop or with assigning values to the views.
CraftingExpandableListAdapter:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val iconListSize = craftingExpandableList[position].requiredList?.icon?.size
val amountListSize = craftingExpandableList[position].requiredList?.amount?.size
if (iconListSize!! > 0 || amountListSize!! > 0) {
val icons = craftingExpandableList[position].requiredList?.icon
val amounts = craftingExpandableList[position].requiredList?.amount
// Create a LinearLayout to hold the views
val verticalLinearLayout = LinearLayout(mContext)
verticalLinearLayout.orientation = LinearLayout.VERTICAL
verticalLinearLayout.setBackgroundColor(Color.parseColor("#002019"))
for (i in 0 until iconListSize) {
// Create the ImageView and TextView views
val iconView = ImageView(mContext)
val amountView = TextView(mContext)
// Set the image resource and text for the views
iconView.setImageResource(icons!![i])
amountView.text = amounts!![i].toString()
// Create a horizontal LinearLayout to hold the views
val horizontalLinearLayout = LinearLayout(mContext)
horizontalLinearLayout.orientation = LinearLayout.HORIZONTAL
// Set the size and margins of the ImageView view
val layoutParams = LinearLayout.LayoutParams(dpToPx(50), dpToPx(50))
layoutParams.setMargins(dpToPx(16), dpToPx(16), 0, dpToPx(16))
iconView.layoutParams = layoutParams
// Set the margins of the TextView view
val textLayoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
textLayoutParams.gravity = Gravity.CENTER_VERTICAL
textLayoutParams.setMargins(dpToPx(16), 0, 0, 0)
amountView.layoutParams = textLayoutParams
// Set the font of the TextView view
// Set the typeface of the TextView view
amountView.typeface = ResourcesCompat.getFont(mContext!!, R.font.roboto_bold)
amountView.setTextColor(Color.parseColor("#F6E9E0"))
// Add the views to the horizontal LinearLayout
horizontalLinearLayout.addView(iconView)
horizontalLinearLayout.addView(amountView)
// Add the horizontal LinearLayout to the vertical LinearLayout
verticalLinearLayout.addView(horizontalLinearLayout)
}
// Add the vertical LinearLayout to the holder's ViewGroup
holder.viewGroup.addView(verticalLinearLayout)
}
}
Additionally my CraftingListModel:
data class CraftingListModel(
val icon: Int = 0,
val name: String = "",
val type: String = "",
val requiredList: RequiredList? = null
)
fun CraftingListModel.toListModel(): List<CraftingListModel> {
val list = mutableListOf<CraftingListModel>()
val requiredList = mutableListOf<RequiredList>()
requiredList.add(RequiredList(listOf(R.raw.high_quality_metal_icon, R.raw.gears_icon), listOf(20, 5)))
requiredList.add(RequiredList(listOf(R.raw.high_quality_metal_icon, R.raw.gears_icon), listOf(30, 5)))
list.add(CraftingListModel(R.raw.armored_door_icon, "Armored Door", "Construction", requiredList[0]))
list.add(CraftingListModel(R.raw.armored_double_door_icon, "Armored Double Door", "Construction", requiredList[1]))
return list
}
and RequiredList:
data class RequiredList(
val icon: List<Int> = emptyList(),
val amount: List<Int> = emptyList()
)
I want to set my chart's data color
So, I found that MPAndroidchart, but example was made Java, not Kotlin.
This is my Kotlin source. How can I change colors?
In Addition, I want to make Label in Bar chart below the bar (Like first picture), And Piechart
Please help me.. T_T
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_result)
val tabHost = findViewById<TabHost>(R.id.TabHost)
tabHost.setup()
//종합 탭 소스
val tabSpecTotal = tabHost.newTabSpec("Total").setIndicator("종합")
tabSpecTotal.setContent(R.id.total)
//남녀 성비 그래프
sexRateChart.setUsePercentValues(true)
sexRateChart.description.setEnabled(false)
sexRateChart.setExtraOffsets(5f, 10f, 5f, 5f)
sexRateChart.dragDecelerationFrictionCoef = 0.95f
sexRateChart.isDrawHoleEnabled = false
sexRateChart.setHoleColor(Color.BLACK)
sexRateChart.transparentCircleRadius = 61f
val sexValues = ArrayList<PieEntry>() // 데이터 삽입
sexValues.add(PieEntry(63f,"남성"))
sexValues.add(PieEntry(37f,"여성"))
sexRateChart.animateY(2000, Easing.EaseInOutCubic) //애니메이션 효과 설정
val sexDataSet = PieDataSet(sexValues, "성별")
sexDataSet.sliceSpace = 3f
sexDataSet.selectionShift = 2f
val sexData = PieData((sexDataSet))
sexData.setValueTextSize(10f)
sexData.setValueTextColor(Color.BLACK)
sexRateChart.setData(sexData)
sexRateChart.invalidate()
//남녀 성비 끝
//연령대 막대그래프
ageRateChart.setExtraOffsets(5f, 10f, 5f, 5f)
val ageValues = ArrayList<BarEntry>()
ageValues.add(BarEntry(0f, 10f, "10대"))
ageValues.add(BarEntry(1f, 30f, "20대"))
ageValues.add(BarEntry(2f, 50f, "30대"))
ageValues.add(BarEntry(3f, 30f, "40대"))
ageValues.add(BarEntry(4f, 40f, "50대"))
ageValues.add(BarEntry(5f, 5f, "60대 이상"))
ageRateChart.animateY(4000, Easing.EaseInOutCubic)
val ageDataSet = BarDataSet(ageValues, "연령대")
ageDataSet.setColors(intArrayOf(R.color.red1, R.color.red2, R.color.red3, R.color.red4), Context)
val ageData = BarData(ageDataSet)
ageData.barWidth = 1f
ageRateChart.data = ageData
ageRateChart.setFitBars(true)
ageRateChart.invalidate()
//연령대 막대그래프 끝
Result of code :
You can set colors with fills
val startColor1 = ContextCompat.getColor(this, android.R.color.holo_orange_light)
val startColor2 = ContextCompat.getColor(this, android.R.color.holo_blue_light)
val startColor3 = ContextCompat.getColor(this, android.R.color.holo_orange_light)
val startColor4 = ContextCompat.getColor(this, android.R.color.holo_green_light)
val startColor5 = ContextCompat.getColor(this, android.R.color.holo_red_light)
val gradientFills: MutableList<Fill> = ArrayList()
with(gradientFills) {
add(Fill(startColor1))
add(Fill(startColor2))
add(Fill(startColor3))
add(Fill(startColor4))
add(Fill(startColor5))
}
val ageDataSet = BarDataSet(ageValues, "연령대")
ageDataSet.fills = gradientFills
And Label with ValueFormatter
ageRateChart.xAxis.apply {
position = XAxisPosition.BOTTOM
setDrawGridLines(false)
granularity = 1f
valueFormatter = object : ValueFormatter() {
override fun getAxisLabel(value: Float, axis: AxisBase?): String {
return (value * 10 + 10).toString() + "대"
}
}
}
I'm currently using a Table Layout and programatically adding rows and buttons. However, when I add the views a lot of them go off-screen. Is there a way to programatically set the size to the portion of the screen.
I have decent experience with Android, but new to Kotlin.
Here is where I add the views
private fun setupTable () {
for(i in 0 until this.rowSize) {
val row = TableRow(context)
row.layoutParams
row.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
for(j in 0 until this.columnSize) {
val button = Button(context)
button.apply {
layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT)
text = "R $i C $j"
}
row.addView(button)
}
wordLayout?.addView(row)
}
}
Here is the picture for reference. Here I want a 10x10 table and to fit all the buttons inside the TableLayout.
Try the following code:
package net.androidly.androidlylayouts
class MainActivity : AppCompatActivity() {
val ROWS = 10
val COLUMNS = 5
val tableLayout by lazy { TableLayout(this) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
textView.text = "ROWS : $ROWS COLUMNS: $COLUMNS"
val lp = TableLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
tableLayout.apply {
layoutParams = lp
isShrinkAllColumns = true
}
createTable(ROWS, COLUMNS)
}
fun createTable(rows: Int, cols: Int) {
for (i in 0 until rows) {
val row = TableRow(this)
row.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
for (j in 0 until cols) {
val button = Button(this)
button.apply {
layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT)
text = "R $i C $j"
}
row.addView(button)
}
tableLayout.addView(row)
}
linearLayout.addView(tableLayout)
}
}
Hope this helps.
I am trying to subclass ConstraintLayout to build a dynamic menu that I can pass in items and it will build a View with sub-views set up. I seem to be struggling with, in Kotlin, laying out things horizontally
I've tried a few things, I've tried laying the items out and constraining them to each other, with the first and last items constrained to the parent. and I've tried using a ConstraintSet for the multiple chain
This is how I initialize it.
val menuLayout = ManageableMenu(tc,listOf(
ManageableMenu.ManageableMenuItem("Item 1"),
ManageableMenu.ManageableMenuItem("Item 2"),
ManageableMenu.ManageableMenuItem("Item 3"),
ManageableMenu.ManageableMenuItem("Item 4")
))
menuLayout.listener = this
val menuLayoutConstraint =menuLayout .layoutParams as ConstraintLayout.LayoutParams
menuLayoutConstraint.topToBottom = actorName.id
menuLayoutConstraint.startToStart = thisLayout.id
menuLayoutConstraint.endToEnd = thisLayout.id
thisLayout.addView(menuLayout)
I tried...
class ManageableMenu(context: Context, val items: List<ManageableMenuItem>): ConstraintLayout(context) {
var textSize: Int = 17
var textColor: Int = Color.WHITE
var activeFragmentTitle: String = items[0].title
var listener: ManageableMenuChangeListener? = null
init {
this.id = View.generateViewId()
this.layoutParams =
ConstraintLayout.LayoutParams(convertToDP(100, this.context), ConstraintLayout.LayoutParams.WRAP_CONTENT)
val baseConstraint = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
)
this.setBackgroundColor(Color.BLACK)
//Build Dividers
val dividers: MutableList<TextView> = mutableListOf()
if (items.size > 1) {
repeat(items.size - 1) {
val newView = TextView(this.context)
newView.id = View.generateViewId()
newView.text = "|"
newView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize + 8.toFloat())
newView.setTextColor(textColor)
dividers.add(newView)
}
}
val constraintSet = ConstraintSet()
constraintSet.clone(this)
val dividerIds: IntArray = IntArray(dividers.size)
for ((index, divider) in dividers.withIndex()) {
dividerIds.set(index, divider.id)
}
constraintSet.createHorizontalChainRtl(
dividerIds[0],
ConstraintSet.START,
this.id,
ConstraintSet.END,
dividerIds,
null,
ConstraintSet.CHAIN_SPREAD
)
constraintSet.applyTo(this)
for (divider in dividers) {
this.addView(divider)
}
}
data class ManageableMenuItem(val title: String) {
var id: Int? = null
}
interface ManageableMenuChangeListener {
fun onMenuItemChanged(var1: String)
}
}
This puts a stack of all "|" created on top of each other, all the way to the left of the view. (If I can attach pictures I will)
I also tried...
class ManageableMenu(context: Context, val items: List<ManageableMenuItem>): ConstraintLayout(context) {
var textSize: Int = 17
var textColor: Int = Color.WHITE
var activeFragmentTitle: String = items[0].title
var listener: ManageableMenuChangeListener? = null
init {
this.id = View.generateViewId()
this.layoutParams =
ConstraintLayout.LayoutParams(convertToDP(100, this.context), ConstraintLayout.LayoutParams.WRAP_CONTENT)
val baseConstraint = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
)
this.setBackgroundColor(Color.BLACK)
//Build Dividers
val dividers: MutableList<TextView> = mutableListOf()
if (items.size > 1) {
repeat(items.size - 1) {
val newView = TextView(this.context)
newView.id = View.generateViewId()
newView.text = "|"
newView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize + 8.toFloat())
newView.setTextColor(textColor)
dividers.add(newView)
}
}
for ((index, divider )in dividers.withIndex()) {
val constraint = ConstraintLayout.LayoutParams(baseConstraint)
constraint.topToTop = this.id
constraint.bottomToBottom = this.id
if (index == 0){
constraint.leftToLeft = this.id
constraint.rightToLeft = dividers[index+1].id
} else if (index == dividers.lastIndex) {
constraint.rightToRight = this.id
constraint.leftToRight = dividers[index-1].id
} else {
constraint.rightToLeft = dividers[index+1].id
constraint.leftToRight = dividers[index-1].id
}
divider.layoutParams = constraint
this.addView(divider)
}
}
data class ManageableMenuItem(val title: String) {
var id: Int? = null
}
interface ManageableMenuChangeListener {
fun onMenuItemChanged(var1: String)
}
}
This aligns a stack of "|" centered in the view. What am I doing wrong?! Any help appreciated! Thanks.
The arguments to createHorizontalChainRtl according to the documentation are
public void createHorizontalChainRtl (int startId,
int startSide,
int endId,
int endSide,
int[] chainIds,
float[] weights,
int style)
You specify the following:
constraintSet.createHorizontalChainRtl(
dividerIds[0],
ConstraintSet.START,
this.id,
ConstraintSet.END,
dividerIds,
null,
ConstraintSet.CHAIN_SPREAD
)
Try changing dividerIds[0] (startId) and this.id (endId) to ConstraintSet.PARENT_ID to form the chain.
I am having problem in the View during notifyDataSetChanged in recyclerView. I implemented pull torefresh logic. So I refresh my RecyclerView and call notifyDataSetChanged. I create a linear layout dynamically and add it to the parent view. The Dynamic linear layout has images. It displays correctly when it loads initially. During pull to refresh, the images loads but disappears immediately. I couldnot understand what the problem would be?
Part of BindViewHolder
if(tempAvailable == true && heartAvailable == true && lungAvailable == true) {
for(i in 1..3) {
if(i == 1) {
val df = DecimalFormat("#.##");
var childLinearLayout:LinearLayout? = createChildView(BitmapFactory.decodeResource(context.getResources(), R.drawable.temperature), df.format(coreBodyTemp).toString(), context.getString(R.string.temperatureStr))
parentLinearLayout.addView(childLinearLayout)
//childLinearLayout = null
} else if(i == 2) {
var childLinearLayout:LinearLayout? = createChildView(BitmapFactory.decodeResource(context.getResources(), R.drawable.heart), heartRate.toString(), context.getString(R.string.heartRate))
parentLinearLayout.addView(childLinearLayout)
//childLinearLayout = null
} else if(i == 3) {
var childLinearLayout:LinearLayout? = createChildView(BitmapFactory.decodeResource(context.getResources(), R.drawable.lung), "", "")
parentLinearLayout.addView(childLinearLayout)
// childLinearLayout = null
}
}
} else if (tempAvailable) {
val df = DecimalFormat("#.##");
var childLinearLayout:LinearLayout? = createChildView(BitmapFactory.decodeResource(context.getResources(), R.drawable.temperature), df.format(coreBodyTemp).toString()+" \u00B0F", context.getString(R.string.temperatureStr))
parentLinearLayout.addView(childLinearLayout)
//childLinearLayout = null
} else if (heartAvailable) {
var childLinearLayout:LinearLayout? = createChildView(BitmapFactory.decodeResource(context.getResources(), R.drawable.heart), heartRate.toString()+" bpm", context.getString(R.string.heartRate))
parentLinearLayout.addView(childLinearLayout)
// childLinearLayout = null
} else if (lungAvailable) {
var childLinearLayout:LinearLayout? = createChildView(BitmapFactory.decodeResource(context.getResources(), R.drawable.lung), "", "")
parentLinearLayout.addView(childLinearLayout)
//childLinearLayout = null
}
The method which creates linear layout dynamically
fun createChildView(icon: Bitmap,readingVal: String, readingTag: String) : LinearLayout {
val lp = LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT)
lp.weight = 1f
val parent: LinearLayout = LinearLayout(context)
parent.setOrientation(LinearLayout.HORIZONTAL)
parent.setLayoutParams(lp)
val imageView = ImageView(context)
val layoutParams = LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT)
layoutParams.weight = 0.4f
layoutParams.height = 60
layoutParams.width = 60
layoutParams.leftMargin = 10
layoutParams.rightMargin = 10
layoutParams.topMargin = 10
layoutParams.bottomMargin =10
imageView.setLayoutParams(layoutParams)
imageView.setImageBitmap(icon)
parent.addView(imageView)
val readingLayout = LinearLayout(context)
readingLayout.setOrientation(LinearLayout.VERTICAL)
val lp1 = LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT)
lp1.weight = 0.6f
lp1.topMargin = 10
readingLayout.setLayoutParams(lp)
val displayValue = TextView(context)
val layoutParams1 = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 0)
layoutParams1.weight = 0.7f
layoutParams1.topMargin = 24
layoutParams1.bottomMargin = 4
displayValue.setLayoutParams(layoutParams1)
displayValue.setText(readingVal)
displayValue.setTextSize(12f)
displayValue.setTextColor(Color.BLACK)
readingLayout.addView(displayValue)
val displayTag = TextView(context)
layoutParams1.weight = 0.3f
layoutParams1.topMargin = 0
displayTag.setLayoutParams(layoutParams1)
displayTag.setText(readingTag)
displayTag.setTextSize(8f)
displayTag.setTextColor(Color.BLACK)
displayTag.setAlpha(0.6f)
readingLayout.addView(displayTag)
parent.addView(readingLayout)
return parent
}
UPDATE:
I fixed this issue by putting setHasStableIds(true) in Recycler view constructor
From Android documentation,
setHasStableIds
void setHasStableIds (boolean hasStableIds)
Indicates whether each item in the data set can be represented with a
unique identifier of type Long.
You must set setHasStableIds(true) for your recycle view