user12359355
user12359355

Reputation:

how to make style "inherit" from layout in custom view class with children?

i have a layout called card.xml which is a "basic" layout for custom class called Card.kt. i have a style for it (@style/homepage_block), and it works for basic case.

card.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:divider="@drawable/separator_horizontal_empty_10"
    android:showDividers="middle"
    style="@style/homepage_block">

    <!-- i set orientation and divider -->

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/block_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/homepage_block_title">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="TITLE"
            style="@style/text.Header" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

Card.kt

package com.tempapplication.views

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import com.tempapplication.R
import com.tempapplication.databinding.CardBinding


class Card @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0, defStyleRes: Int = 0
) : LinearLayout(context, attrs, defStyleAttr, defStyleRes) {

    private val binding: CardBinding

    init {
        LayoutInflater.from(context).inflate(R.layout.card, this, true)
        binding = CardBinding.bind(this)
        initAttributes(attrs, defStyleAttr, defStyleRes)
    }

    // i have a custom attribute called title which i use to set the title text
    private fun initAttributes(attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) {
        if (attrs == null) { return }
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.Card, defStyleAttr, defStyleRes)
        binding.title.text = typedArray.getString(R.styleable.Card_title)
        typedArray.recycle()
    }

    override fun addView(child: View?, params: ViewGroup.LayoutParams?) {
        super.addView(child, params)
    }
}

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="Card">
        <attr name="title" format="string" />
    </declare-styleable>

</resources>

so the further question can be broken in two pieces.

first question

can i somehow "inherit" attributes from card.xml to custom view in which i use this layout? for example, in card.xml i set the linear layout orientation to vertical and also have a custom divider. but when i include custom view in some activity it simply seems to don't know about it (this is how it supposed to look like, and this how it actually looks like), so i have to manually set divider and orientation when including this custom view.

piece of activity.xml

<com.tempapplication.views.Card
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:divider="@drawable/separator_horizontal_empty_10" 
        android:showDividers="middle"
        app:title="PAGE OF WEEK" >

        <!-- i set orientation and divider even when they are set in card.xml -->

        <include
            layout="@layout/content_week"
            bind:data="@{data.week}"/>

</com.tempapplication.views.Card>

maybe i need to put the dividers and orientation in style resource? or is there a more elegant way to do this?

second question

i have child views (like in code above when including layout content_week). how do i make initial card.xml style of root linear layout (@style/homepage_block) affect children i include in the Card view? for example, i want all children of Card have red background because of style resource used in card.xml. is it possible?

content_week.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable name="data" type="com.tempapplication.modules.HomepageBlockWeekData"/>
    </data>

    <LinearLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:divider="@drawable/separator_horizontal_empty_10"
        android:showDividers="middle"
        style="@style/homepage_block_content">

        <TextView
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:gravity="center_vertical"
            android:text="@{data.title}"
            style="@style/text.Header" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/_1pxh"
            android:backgroundTint="#FFCAC4D0"
            android:background="@drawable/separator" />

        <TextView
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:text="@{data.description}"
            style="@style/text" />
    </LinearLayout>
</layout>

Upvotes: 2

Views: 199

Answers (0)

Related Questions