Чтение пользовательского атрибута макета из дочерних представлений в пользовательском макете - PullRequest
0 голосов
/ 13 мая 2018

Я создал свой собственный макет.И я определил «хороший» атрибут для использования в его дочерних представлениях.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyLayout">
        <attr name="good" format="boolean" />
    </declare-styleable>
</resources>

Атрибут используется следующим образом.Это похоже на то, что вы можете использовать android:layout_centerInParent для дочерних представлений RelativeLayout, хотя я не уверен, почему мой должен начинаться с "app:", а это начинается с "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>

Теперь я хочу прочитать этот атрибут от детей.Но как?Я искал в Интернете и попробовал несколько вещей, но, похоже, это не сработало.

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")
        }
    }
}

Добавлено: С комментарием в качестве подсказки я нашел этот документ и изменил мой код, как показано ниже, и теперь я получаю желаемый результат.

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()
            }
        }
    }
}
...