I'm generating my (constraint)layout programmatically.
Everything shows up as it's supposed to, with proper constraints, but I can't make my views MATCH_CONSTRAINT width to spread as it's supposed to (like when you set 0dp when making it with XML).
I found this:
Set ConstraintLayout width to match parent width programmatically
helpful, but doesn't work at all.
Posting my layout generaitng function below:
private fun generateLayout(formData: Form) {
val decodedBytes = Base64.getDecoder().decode(formData.form)
val decodedString = String(decodedBytes)
val gson = Gson()
val formFields = gson.fromJson(decodedString, Array<FormField>::class.java).asList()
val constraintLayout: ConstraintLayout = findViewById(R.id.constraintLayout)
val constraintSet = ConstraintSet()
val layoutParams = ConstraintLayout.LayoutParams(0, WRAP_CONTENT)
var views: ArrayList<View> = ArrayList()
var formFieldsCounter: Int = 0
//parsing fields form model class to actual view
formFields.forEach {
var view: View? = null
view?.layoutParams = layoutParams
when (it.type) {
"textField" -> {
view = EditText(this)
view.hint = it.fieldName
}
"checkBox" -> {
view = CheckBox(this)
//view.isChecked = it.isChecked
}
}
view!!.id = it.id!!
view.visibility = View.VISIBLE
views.add(view)
constraintLayout.addView(view)
}
//set constraints between created views
constraintSet.clone(constraintLayout)
views.forEach {
constraintSet.constrainDefaultWidth(it.id, ConstraintSet.MATCH_CONSTRAINT_SPREAD)
//TOP CONSTRAINT
if (formFields[formFieldsCounter].layout_constraintTop_toSBottmOf == 0)
constraintSet.connect(
it.id,
ConstraintSet.TOP,
R.id.applicationNumberTextView,
ConstraintSet.BOTTOM
)
else if (formFields[formFieldsCounter].layout_constraintTop_toSBottmOf != null)
constraintSet.connect(
it.id,
ConstraintSet.TOP,
formFields[formFieldsCounter].layout_constraintTop_toSBottmOf!!,
ConstraintSet.BOTTOM
)
//BOTTOM CONSTRAINT
if (formFields[formFieldsCounter].layout_constraintBottom_toTopOf == 0)
constraintSet.connect(
it.id,
ConstraintSet.BOTTOM,
R.id.parent,
ConstraintSet.TOP
)
else if (formFields[formFieldsCounter].layout_constraintBottom_toTopOf != null)
constraintSet.connect(
it.id,
ConstraintSet.BOTTOM,
formFields[formFieldsCounter].layout_constraintBottom_toTopOf!!,
ConstraintSet.TOP
)
//LEFT CONSTRAINT
if (formFields[formFieldsCounter].layout_constraintStart_toSEndOf == 0)
constraintSet.connect(
it.id,
ConstraintSet.LEFT,
R.id.parent,
ConstraintSet.LEFT
)
else if (formFields[formFieldsCounter].layout_constraintStart_toSEndOf != null)
constraintSet.connect(
it.id,
ConstraintSet.LEFT,
formFields[formFieldsCounter].layout_constraintStart_toSEndOf!!,
ConstraintSet.RIGHT
)
//RIGHT CONSTRAINT
if (formFields[formFieldsCounter].layout_constraintEnd_toStartOf == 0)
constraintSet.connect(
it.id,
ConstraintSet.RIGHT,
R.id.parent,
ConstraintSet.RIGHT
)
else if (formFields[formFieldsCounter].layout_constraintEnd_toStartOf != null)
constraintSet.connect(
it.id,
ConstraintSet.RIGHT,
formFields[formFieldsCounter].layout_constraintEnd_toStartOf!!,
ConstraintSet.LEFT
)
formFieldsCounter++
}
constraintSet.applyTo(constraintLayout)
}
This is what i get:
It's pretty much the same what I get without setting
view?.layoutParams = layoutParams
or
constraintSet.constrainDefaultWidth(it.id, ConstraintSet.MATCH_CONSTRAINT_SPREAD)
I'm stuck with it for a while now. Thanks a million for any help :)
Related
I have a problem and I don't know how I could create a function to save the state of a MutableListOf when the application is closed and another one to restore it when it is opened again. Could someone help me?
Code:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button = findViewById<Button>(R.id.button)
val text = findViewById<TextView>(R.id.editTextTextPersonName)
val layout = findViewById<ConstraintLayout>(R.id.layout)
var numbers = 0
var checkboxes = mutableListOf<CheckBox>()
button.setOnClickListener {
val checkbox = CheckBox(this)
checkbox.text = text.text
text.text = ""
checkbox.textSize = 13f
val font = Typeface.create(Typeface.MONOSPACE, Typeface.BOLD)
checkbox.typeface = font
layout.addView(checkbox)
val params = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
)
params.setMargins(100, numbers * 75, 100, 100)
params.width = 1020
params.height = 120
checkbox.layoutParams = params
checkbox.id = View.generateViewId()
val constraintSet = ConstraintSet()
constraintSet.clone(layout)
constraintSet.connect(
checkbox.id,
ConstraintSet.TOP,
layout.id,
ConstraintSet.TOP,
numbers * 75
)
constraintSet.connect(
checkbox.id,
ConstraintSet.START,
layout.id,
ConstraintSet.START,
0
)
constraintSet.applyTo(layout)
numbers += 1
checkboxes.add(checkbox)
checkbox.setOnClickListener {
checkbox.animate().alpha(1f).withEndAction {
checkbox.isChecked = false
layout.removeView(checkbox)
numbers -= 1
checkboxes.remove(checkbox)
checkboxes.forEachIndexed { index, cb ->
val params = cb.layoutParams as ConstraintLayout.LayoutParams
params.setMargins(0, index * 75, 0, 0)
cb.layoutParams = params
val constraintSet = ConstraintSet()
constraintSet.clone(layout)
constraintSet.connect(
cb.id,
ConstraintSet.TOP,
layout.id,
ConstraintSet.TOP,
index * 75
)
constraintSet.applyTo(layout)
}
}.start()
}
}
}
}
I have tried many things but none of them have worked
I want to create a tree layout dynamically using constraint layout.
Something like this:
With tree child nodes retrieved at runtime.
Specifications:
1. All nodes can have a maximum of three child nodes.
2. The whole layout must be created programmatically.
3. Null is passed in data if a node does not have a child.
What I tried:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
createTree(treeNode)
}
private fun createTree(treeNode: TreeNode) {
val rootView: ConstraintLayout = dataBinding.root as ConstraintLayout
val treeView = createLayout(treeNode, 0)
if (treeView != null) {
val mainViewConstraintSet = ConstraintSet()
mainViewConstraintSet.clone(treeView)
mainViewConstraintSet.connect(
rootView.id,
ConstraintSet.START,
treeView.id,
ConstraintSet.START
)
mainViewConstraintSet.connect(
rootView.id,
ConstraintSet.END,
treeView.id,
ConstraintSet.END
)
mainViewConstraintSet.applyTo(treeView)
rootView.addView(treeView)
Log.e("Log", "Added Root View")
}
}
private fun createLayout(treeNode: TreeNode?, depth: Int): ConstraintLayout? {
if (depth > 1) {
return null
}
if (treeNode == null) {
return null
}
val layoutView = ConstraintLayout(context)
val layoutViewLayoutParams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
)
layoutViewLayoutParams.topMargin = 16
layoutViewLayoutParams.leftMargin = 16
layoutViewLayoutParams.rightMargin = 16
layoutViewLayoutParams.bottomMargin = 16
layoutView.layoutParams = layoutViewLayoutParams
layoutView.setBackgroundColor(Color.CYAN)
layoutView.id = ViewCompat.generateViewId()
val layoutNode = createNode(treeNode.user)
Log.e("Log", "Created node for " + treeNode.user.name)
val leftChildLayout = createLayout(treeNode.left, depth + 1)
val middleChildLayout = createLayout(treeNode.middle, depth + 1)
val rightChildLayout = createLayout(treeNode.right, depth + 1)
val mainViewConstraintSet = ConstraintSet()
mainViewConstraintSet.connect(
layoutNode.id,
ConstraintSet.TOP,
layoutView.id,
ConstraintSet.TOP,
16
)
mainViewConstraintSet.connect(
layoutNode.id,
ConstraintSet.BOTTOM,
layoutView.id,
ConstraintSet.BOTTOM,
16
)
mainViewConstraintSet.connect(
layoutNode.id,
ConstraintSet.START,
layoutView.id,
ConstraintSet.START,
16
)
mainViewConstraintSet.connect(
layoutNode.id,
ConstraintSet.END,
layoutView.id,
ConstraintSet.END,
16
)
if (leftChildLayout != null) {
mainViewConstraintSet.connect(
layoutNode.id,
ConstraintSet.BOTTOM,
leftChildLayout.id,
ConstraintSet.TOP,
16
)
}
if (middleChildLayout != null) {
mainViewConstraintSet.connect(
layoutNode.id,
ConstraintSet.BOTTOM,
middleChildLayout.id,
ConstraintSet.TOP,
16
)
}
if (rightChildLayout != null) {
mainViewConstraintSet.connect(
layoutNode.id,
ConstraintSet.BOTTOM,
rightChildLayout.id,
ConstraintSet.TOP,
16
)
}
if (leftChildLayout != null && middleChildLayout != null) {
mainViewConstraintSet.connect(
leftChildLayout.id,
ConstraintSet.END,
middleChildLayout.id,
ConstraintSet.START,
16
)
mainViewConstraintSet.connect(
middleChildLayout.id,
ConstraintSet.END,
leftChildLayout.id,
ConstraintSet.START,
16
)
}
if (rightChildLayout != null && middleChildLayout != null) {
mainViewConstraintSet.connect(
middleChildLayout.id,
ConstraintSet.END,
rightChildLayout.id,
ConstraintSet.START,
16
)
mainViewConstraintSet.connect(
rightChildLayout.id,
ConstraintSet.END,
middleChildLayout.id,
ConstraintSet.START,
16
)
}
mainViewConstraintSet.applyTo(layoutView)
// layoutView.setConstraintSet(mainViewConstraintSet)
if (leftChildLayout != null) {
layoutView.addView(leftChildLayout)
}
if (middleChildLayout != null) {
layoutView.addView(middleChildLayout)
}
if (rightChildLayout != null) {
layoutView.addView(rightChildLayout)
}
layoutView.addView(layoutNode)
return layoutView
}
private fun createNode(user: User): ConstraintLayout {
val node = ConstraintLayout(context)
node.id = ViewCompat.generateViewId()
val nodeTextView = TextView(context)
nodeTextView.id = ViewCompat.generateViewId()
nodeTextView.text = user.name
nodeTextView.textSize = 18f
nodeTextView.setTextColor(Color.BLACK)
nodeTextView.setTypeface(null, Typeface.BOLD)
val layoutParams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT
)
nodeTextView.layoutParams = layoutParams
nodeTextView.setBackgroundColor(Color.GREEN)
val constraintSet = ConstraintSet()
constraintSet.clone(node)
constraintSet.connect(nodeTextView.id, ConstraintSet.TOP, node.id, ConstraintSet.TOP, 16)
constraintSet.connect(nodeTextView.id, ConstraintSet.LEFT, node.id, ConstraintSet.LEFT, 16)
constraintSet.applyTo(node)
node.addView(nodeTextView)
node.setBackgroundColor(Color.RED)
return node
}
The Tree Data Model:
data class TreeNode( val user: User, var parent: TreeNode?,
var left: TreeNode?, var middle: TreeNode?, var right: TreeNode?) { }
I know this question has been asked multiple times, but this seems so difficult to achieve through code.
What I am trying to achieve is to extend the ConstraintLayout and add two views to it. I have the following code:
class TestLayout #JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
private val ids = mutableListOf<Int>()
init {
addTextView()
addTextView()
val set = ConstraintSet()
set.clone(this)
set.connect(ids[0], ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 200)
set.connect(ids[1], ConstraintSet.TOP, ids[0], ConstraintSet.BOTTOM)
set.applyTo(this)
}
private fun addTextView() {
val view = TextView(context)
addView(view, LayoutParams(LayoutParams.MATCH_CONSTRAINT, LayoutParams.WRAP_CONTENT))
view.id = View.generateViewId()
view.text = view.id.toString()
ids.add(view.id)
}
}
When running this code the first view is properly displayed, but the second one is in the top left corner (as if there are no constraints on it).
What exactly am I missing here?
You'll need to add at least one horizontal & one vertical constraint to view adding in ConstraintLayout,
Here, it's not satisfied in init constructor:
set.connect(ids[0], ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 200) // no vertical constraint (Top/Bottom), so view will add at 0 position of y axis
set.connect(ids[1], ConstraintSet.TOP, ids[0], ConstraintSet.BOTTOM) // No horizontal constraint so that view 2 will jump to position (0,0)
Do like this:
// Add constraints for View 1
set.connect(ids[0], ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 200)
set.connect(ids[0], ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 20) // Add top constraint to your view 1
set.connect(ids[0], ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 200) // Optional if you want symmetry of view 1 in layout
// Add constraints for view 2
set.connect(ids[1], ConstraintSet.TOP, ids[0], ConstraintSet.BOTTOM)
set.connect(ids[1], ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 200) // Add start constraint to view 2
set.connect(ids[1], ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 200) // Optional if you want symmetry of view 2 in layout
Read it from ConstraintLayout & ConstraintSet.
I've the below code, in which I construct a "card" and adding to it both Switch and button, I need the button to be exactly under the switch, how to make it!
val swithy = Switch(this).apply {
text = "active"
isChecked = true
id = View.generateViewId()
}
val mcard = CardView(this).apply {
background = getDrawable(R.drawable.card_background)
radius = 12F
setContentPadding(25, 25, 25, 25)
setCardBackgroundColor(Color.LTGRAY)
cardElevation = 8F
maxCardElevation = 12F
addView(swithy, RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT).apply {
RelativeLayout.ALIGN_PARENT_BOTTOM
RelativeLayout.ALIGN_PARENT_LEFT
})
addView(Button(this.context).apply {
text = "click me"
}, LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT).apply {
/* addRule(RelativeLayout.BELOW, swithy.id); */
// How to make this?! it works in Java, how to make it in Kotlin
})
}
card_background.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
android:name="custom_view"
android:id="#+id/custom_view">
<stroke
android:width="1dp"
android:color="#c2f2f2f2" />
<solid
android:color="#FFFFFFFF"
/>
<corners
android:bottomRightRadius="2dp"
android:bottomLeftRadius="2dp"
android:topLeftRadius="2dp"
android:topRightRadius="2dp" />
</shape>
I was able to manage my requirements using ConstraintLayout, I'm posting my answer here, may some people find it helpful:
In MainActivity.kt I'm calling my custom element as:
main_layout.addView(Cardy(this))
My custom element Cardy.kt is:
import android.content.Context
import android.support.constraint.ConstraintLayout
import android.support.v4.content.ContextCompat
import android.widget.Button
import oryx.kortex.locateme.R
import android.graphics.Color
import android.support.constraint.ConstraintSet
import android.widget.EditText
import android.util.TypedValue
class Cardy : ConstraintLayout {
constructor(context: Context) : super(context) {
init(context)
}
private fun init(context: Context) {
val r = resources
val px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 200f,
r.displayMetrics).toInt()
val myEditText = EditText(context).apply {
id = ConstraintLayout.generateViewId()
width = px
}
val myButton = Button(context).apply {
text = "Press Me"
setBackgroundColor(Color.BLUE)
id = ConstraintLayout.generateViewId()
}
this.apply {
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
background = ContextCompat.getDrawable(context, R.drawable.card)
addView(myButton)
addView(myEditText)
}
val set = ConstraintSet().apply {
constrainHeight(myButton.id, ConstraintSet.WRAP_CONTENT)
constrainWidth(myButton.id, ConstraintSet.WRAP_CONTENT)
connect(myButton.id, ConstraintSet.LEFT,
ConstraintSet.PARENT_ID, ConstraintSet.LEFT, 0)
connect(myButton.id, ConstraintSet.RIGHT,
ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0)
connect(myButton.id, ConstraintSet.TOP,
ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0)
connect(myButton.id, ConstraintSet.BOTTOM,
ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0)
constrainHeight(myEditText.id, ConstraintSet.WRAP_CONTENT)
constrainWidth(myEditText.id, ConstraintSet.WRAP_CONTENT)
connect(myEditText.id, ConstraintSet.LEFT,
ConstraintSet.PARENT_ID, ConstraintSet.LEFT, 0)
connect(myEditText.id, ConstraintSet.RIGHT,
ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0)
connect(myEditText.id, ConstraintSet.BOTTOM,
myButton.id, ConstraintSet.TOP, 70)
}
set.applyTo(this)
}
}
And the output is:
NOTES:
This part is to center the element horizontal:
connect(myButton.id, ConstraintSet.LEFT,
ConstraintSet.PARENT_ID, ConstraintSet.LEFT, 0)
connect(myButton.id, ConstraintSet.RIGHT,
ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0)
This part is to center the element vertically:
connect(myButton.id, ConstraintSet.TOP,
ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0)
connect(myButton.id, ConstraintSet.BOTTOM,
ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0)
To have both elements in the same line, below code do the job:
val set = ConstraintSet().apply {
constrainHeight(myEditText.id, ConstraintSet.WRAP_CONTENT)
constrainWidth(myEditText.id, ConstraintSet.WRAP_CONTENT)
constrainHeight(myButton.id, ConstraintSet.WRAP_CONTENT)
constrainWidth(myButton.id, ConstraintSet.WRAP_CONTENT)
connect(myButton.id, ConstraintSet.RIGHT,
ConstraintSet.PARENT_ID, ConstraintSet.RIGHT,0)
}
It can be done using the below:
RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT).apply {
addRule(RelativeLayout.BELOW, ELEMENT.id)
}
Below is a full running code with me:
val card1 = Switchy(this).apply {
id = ConstraintLayout.generateViewId()
}
val card2 = Cardy(this).apply {
id = ConstraintLayout.generateViewId()
}
main_layout.addView(card1)
main_layout.addView(card2,
RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT).apply {
addRule(RelativeLayout.BELOW, card1.id)
})
main_layout.addView(Settings(this),
RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT).apply {
addRule(RelativeLayout.BELOW, card2.id)
}
)
Where Switchy is:
class Switchy : RelativeLayout {
constructor(context: Context) : super(context) {
init(context)
}
private fun init(context: Context) {
val colorOn = -0xcdc1ba
val trackStates = ColorStateList(
arrayOf(intArrayOf(-android.R.attr.state_checked), intArrayOf()),
intArrayOf(Color.LTGRAY, colorOn)
)
this.apply {
layoutParams = android.widget.RelativeLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
addView(Switch(context).apply {
background = ContextCompat.getDrawable(context, R.drawable.card)
text = "active or not is it ?"
isChecked = true
showText = true
textOn = "Active"
textOff = "Not Active"
trackTintList = trackStates
thumbTintList = trackStates
}, LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT))
}
}
}
And Cardy is:
class Cardy : ConstraintLayout {
constructor(context: Context) : super(context) {
init(context)
}
private fun init(context: Context) {
val r = resources
val px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 200f,
r.displayMetrics).toInt()
val myEditText = EditText(context).apply {
id = ConstraintLayout.generateViewId()
width = px
}
val myImageButton = ImageButton(context).apply({
background = null
setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_save_black_24px))
})
val myButton = Button(context).apply {
text = "Press Me"
setBackgroundColor(Color.BLUE)
id = ConstraintLayout.generateViewId()
}
this.apply {
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)
background = ContextCompat.getDrawable(context, R.drawable.card)
addView(myEditText)
// addView(myButton)
addView(myImageButton)
}
val set = ConstraintSet().apply {
constrainHeight(myEditText.id, ConstraintSet.WRAP_CONTENT)
constrainWidth(myEditText.id, ConstraintSet.WRAP_CONTENT)
constrainHeight(myImageButton.id, ConstraintSet.WRAP_CONTENT)
constrainWidth(myImageButton.id, ConstraintSet.WRAP_CONTENT)
connect(myImageButton.id, ConstraintSet.RIGHT,
ConstraintSet.PARENT_ID, ConstraintSet.RIGHT,0)
}
set.applyTo(this)
}
}
LinearLayout also could be an option, below code set a an EditText with ImageButton:
import android.content.Context
import android.support.v4.content.ContextCompat
import android.support.v7.widget.CardView
import android.widget.*
import android.widget.LinearLayout
class RespondTo : CardView {
constructor(context: Context) : super(context) {
init(context)
}
private fun init(context: Context) {
val parent = LinearLayout(context)
parent.apply {
layoutParams = LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT, 1.0f).apply {
orientation = LinearLayout.HORIZONTAL
addView(EditText(context).apply {
id = generateViewId()
layoutParams = LinearLayout.LayoutParams(0,
LinearLayout.LayoutParams.WRAP_CONTENT, 0.9f).apply {
}
})
addView(ImageButton(context).apply({
layoutParams = LinearLayout.LayoutParams(0,
LinearLayout.LayoutParams.WRAP_CONTENT, 0.1f)
background = null
setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_save_black_24px))
id = generateViewId()
layoutParams = RelativeLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT).apply {
addRule(RelativeLayout.ALIGN_PARENT_RIGHT)
// addRule(RelativeLayout.LEFT_OF, myImageButton.id)
}
}))
}
}
this.addView(parent)
}
}
I want to create cardView with anko and set cornerRadius param to it. But When I try to do - no such differents come.
In main class I do this:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup): View {
with(applicationContext!!) {
listView = listView {
layoutParams = ViewGroup.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT)
dividerHeight = 20
}
}
listView?.adapter = CustomAdapter(forms)
return listView!!
}
In CustomAdapter I return cardView like this:
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val currentForm = getItem(position)
return convertView ?: createCardView(parent!!.context, currentForm)
}
private fun createCardView(context: Context, form: FormField): View =
with(context) {
frameLayout {
cardView {
layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT).apply {
leftMargin = dip(10)
rightMargin = dip(10)
topMargin = dip(5)
bottomMargin = dip(5)
}
backgroundColor = Color.WHITE
radius = dip(8).toFloat()
verticalLayout {
// title
textView {
text = form.title
textColor = ContextCompat.getColor(context, R.color.colorPrimary)
textSize = 20f
}.lparams(width = matchParent) {
leftMargin = dip(15)
topMargin = dip(10)
bottomMargin = dip(10)
}
// subtitle
textView {
if (form.subTitle != null) {
text = form.subTitle
textColor = ContextCompat.getColor(context, R.color.colorPrimary)
textSize = 12f
visibility = View.VISIBLE
} else {
visibility = View.GONE
}
}.lparams(width = matchParent) {
leftMargin = dip(15)
topMargin = dip(10)
bottomMargin = dip(10)
}
}.lparams(width = matchParent, height = matchParent)
}
}
}
I try to call 'radius' setter in different ways and values, but result is always like this
As you can see - the corners are always rectangle. What I want - to round the corners with Anko
Small p.s. - when I return from getView inflated xml layout with same cardview - it has rounded corners.
So, the problem was in
backgroundColor = Color.WHITE
It was set the default background DRAWABLE param to ColorDrawable instead inner RoundRectDrawable.
So, when I change this row to :
background.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP)
All start to work and corners become to be rounded
The previous answer didn't help me. That is worked for me:
cardView {
background = GradientDrawable().apply {
shape = GradientDrawable.RECTANGLE
cornerRadius = 8f
setStroke(2, grey)
....
}
}