I created my own layout. And I defined a "good" attribute to use for its child views.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyLayout">
<attr name="good" format="boolean" />
</declare-styleable>
</resources>
The attribute is used like this. It is sort of like you can use android:layout_centerInParent
for child views of a RelativeLayout
, although I am not sure why mine should start with "app:" and that starts with "android:".
<?xml version="1.0" encoding="utf-8"?>
<com.loser.mylayouttest.MyLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
app:good = "true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</com.loser.mylayouttest.MyLayout>
Now I want to read that attribute from children. But how? I have searched the web and tried a few things, but it did not seem to work.
class MyLayout: LinearLayout
{
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)
{
setMeasuredDimension(200, 300); // dummy
for(index in 0 until childCount)
{
val child = getChildAt(index);
val aa = child.context.theme.obtainStyledAttributes(R.styleable.MyLayout);
val good = aa.getBoolean(R.styleable.MyLayout_good, false)
aa.recycle();
Log.d("so", "value = $good")
}
}
}
Added: With the comment as a hint, I found this document, and modified my code like below, and now I get the result I wanted.
class MyLayout: LinearLayout
{
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)
{
setMeasuredDimension(200, 300);
for(index in 0 until childCount)
{
val child = getChildAt(index);
val p = child.layoutParams as MyLayoutParams;
Log.d("so", "value = ${p.good}")
}
}
override fun generateDefaultLayoutParams(): LayoutParams
{
return MyLayoutParams(context, null);
}
override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams
{
return MyLayoutParams(context, attrs);
}
override fun checkLayoutParams(p: ViewGroup.LayoutParams?): Boolean
{
return super.checkLayoutParams(p)
}
inner class MyLayoutParams: LayoutParams
{
var good:Boolean = false;
constructor(c: Context?, attrs: AttributeSet?) : super(c, attrs)
{
if(c!=null && attrs!=null)
{
val a = c.obtainStyledAttributes(attrs, R.styleable.MyLayout);
good = a.getBoolean(R.styleable.MyLayout_good, false)
a.recycle()
}
}
}
}