Search code examples
androidxmlkotlinandroid-layout

How to create custom layout and send reference on image to my custom layout class?


I want to create my custom layout like this: enter image description here

The image arrow always remains the same and does not change.But i want that image email will change depends from image which i want to send there like i using app:srcCompat or android:src

image that i want change in my custom layout

 <ImageView
                android:id="@+id/settings_element_start_icon"
                android:layout_width="32dp"
                android:layout_height="32dp"
                android:layout_marginStart="4dp"
                android:layout_gravity="center"
                />

my SettingsElementView.kt

package com.example.dummyapp.view

import android.content.Context
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.example.dummyapp.R

class
SettingsElementView @JvmOverloads constructor(
    context : Context,
    attributeSet : AttributeSet? = null,
    defStyleAttr: Int = 0 ,
) : LinearLayout(context, attributeSet, defStyleAttr) {


    private val main_text : TextView
    private val title_text : TextView
    private val image_view : ImageView

    init{
        LayoutInflater.from(context).inflate(R.layout.settings_element_view, this, true)
        main_text = findViewById(R.id.settings_element_textview)
        title_text = findViewById(R.id.settings_element_textview_title)
        image_view = findViewById(R.id.settings_element_start_icon)
        

        val typedArray = context.obtainStyledAttributes(attributeSet,R.styleable.SettingsElementView )
        var text = typedArray.getString(R.styleable.SettingsElementView_main_text)
        var title = typedArray.getString(R.styleable.SettingsElementView_title_text)
        var icon = typedArray.getString(R.styleable.SettingsElementView_start_icon)
        typedArray.recycle()

        //Установка значения в TextView
        main_text.text = text
        title_text.text = title
        image_view.setImageDrawable(Drawable.createFromPath(icon))


    }

    fun setMainText(text : String){
        main_text.text = text
    }

}

Like i trying to use it

  <com.example.dummyapp.view.SettingsElementView
        android:id="@+id/sex"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:start_icon="@drawable/phone_icon"
        app:main_text=""
        app:title_text="@string/sex_profile"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/birthday" />

and my attr.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="SettingsElementView">
        <attr name="title_text" format="string"/>
        <attr name="main_text" format="string"/>
        <attr name="start_icon" format="string"/>
    </declare-styleable>

</resources>

Solution

  • When it comes to resources, you have to use format="reference" instead of format="string". Then you can read resource id value from typed array and set drawable to the settings_element_start_icon image.

    Updated attr.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <declare-styleable name="SettingsElementView">
        <attr name="title_text" format="string"/>
        <attr name="main_text" format="string"/>
        <!-- Reference mean we want to load resource -->
        <attr name="start_icon" format="reference"/>
    </declare-styleable>
    </resources>
    

    You can get drawable id from typedArray and set drawable like this:

    // Get drawable id. When attribute is not used, default value (-1) will be returned
    val iconRes = typedArray.getResourceId(R.styleable.SettingsElementView_start_icon, -1)
    if (iconRes != -1) {
        //Load drawable using icon resource id
        image_view.setImageDrawable(ContextCompat.getDrawable(context, iconRes))
    }