1

The simplest way I found to create a custom view, so I don't have to handle annoying things like to override the onLayout() method, is to make it inherit from a LinearLayout. I also have a LinearLayout at the root of the associated XML file that I inflate, so there is 2 of them at the root.

How can I optimise this, by removing one of this extra LinearLayout, but keep it simple to create custom views ?

MyToolbar.kt:

class MyToolbar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) :
    LinearLayoutCompat(context, attrs, defStyleAttr) {

    private val binding = MyToolbarBinding.inflate(LayoutInflater.from(context), this, true)

    init {
         // [...] Initialization of my view ...
    }
}

my_toolbar.xml:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <!-- Actual content of my view -->

</LinearLayout>
Twisha Kotecha
  • 1,082
  • 1
  • 4
  • 18
Bencri
  • 1,173
  • 1
  • 7
  • 22

2 Answers2

0

As Pawel suggested you could use merge to do that.

This is a sample from the developer website:

<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Here you can add your custom content views.. -->
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/add"/>

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/delete"/>

</merge>
Bencri
  • 1,173
  • 1
  • 7
  • 22
Cata
  • 11,133
  • 11
  • 65
  • 86
  • @Pawel You totally skipped the attributes of the `LinearLayout` (width, height, gravity and orientation). I tried to add them programmatically in the `init` function before inflating the subview and it doesn't work. – Bencri Jan 17 '20 at 15:44
0

What I have right now after @Pawel and @Cata suggestion. This doesn't work, the LinearLayout use the whole height of the parent, but it should only wrap its content.

MyToolbar.kt:

class MyToolbar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) :
    LinearLayoutCompat(context, attrs, defStyleAttr) {

    private val binding

    init {
        // Tried to add the attributes here as they seems ignored on the `merge` tag
        gravity = Gravity.CENTER_VERTICAL
        orientation = HORIZONTAL
        layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)

        binding = MyToolbarBinding.inflate(LayoutInflater.from(context), this)

        // [...] Initialization of the view ...
    }
}

my_toolbar.xml:

<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <!-- Actual content of the view -->

</merge>
Bencri
  • 1,173
  • 1
  • 7
  • 22