Sobes.tech
Middle

Como conectar uma visualização personalizada e um layout personalizado?

sobes.tech IA

Resposta da IA

Para conectar uma vista personalizada (herdada de View ou suas subclasses) a um layout personalizado (XML layout), utilizam-se os seguintes mecanismos:

  1. Sobrescrever os construtores da vista: A vista personalizada deve ter construtores que permitam ao sistema Android criá-la a partir de XML. Os mais importantes:

    • public MyCustomView(Context context)
    • public MyCustomView(Context context, AttributeSet attrs)
    • public MyCustomView(Context context, AttributeSet attrs, int defStyleAttr)
    • public MyCustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)

    Nos construtores que aceitam AttributeSet, pode-se obter os atributos definidos em XML.

  2. Uso de <merge> ou <include> quando necessário (para vistas complexas):

    • <include>: Permite incluir o conteúdo de outro layout. Útil para partes reutilizáveis da interface.
    • <merge>: Usado como elemento raiz do layout para evitar níveis desnecessários na hierarquia de vistas, especialmente ao usar <include> com <FrameLayout> ou <LinearLayout>.
  3. Instanciar a vista e inflar o layout: No construtor da vista personalizada (normalmente aquele que aceita AttributeSet), cria-se instâncias das vistas internas e preenche-se o layout.

Exemplo:

// custom_my_view.xml
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textViewTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Title"
        android:textSize="18sp"/>

    <EditText
        android:id="@+id/editTextValue"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter value"/>

</LinearLayout>
// MyCustomView.kt (Classe de vista personalizada)
class MyCustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {

    private val textViewTitle: TextView
    private val editTextValue: EditText

    init {
        // Inflar o layout personalizado
        LayoutInflater.from(context).inflate(R.layout.custom_my_view, this, true)

        // Obter referências às vistas definidas no layout
        textViewTitle = findViewById(R.id.textViewTitle)
        editTextValue = findViewById(R.id.editTextValue)

        // Processar atributos personalizados, se houver
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyleAttr, 0)
        val titleText = typedArray.getString(R.styleable.MyCustomView_titleText)
        typedArray.recycle()

        // Definir valores iniciais com base nos atributos ou padrão
        textViewTitle.text = titleText ?: "Título padrão"
    }

    // Métodos públicos para interagir com as vistas internas
    fun setTitle(title: String) {
        textViewTitle.text = title
    }

    fun getValue(): String {
        return editTextValue.text.toString()
    }
}
<!-- styles.xml (Opcional: definir atributos personalizados) -->
<resources>
    <declare-styleable name="MyCustomView">
        <attr name="titleText" format="string"/>
    </declare-styleable>
</resources>
<!-- activity_main.xml (Usando a vista personalizada) -->
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.seuPacote.MyCustomView
        android:id="@+id/myCustomView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:titleText="Meu Título Personalizado"/>

</LinearLayout>

A ideia é que a classe de vista personalizada (por exemplo, MyCustomView) atua como um contêiner que gerencia as vistas definidas no seu layout personalizado (custom_my_view.xml). Ela "infla" esse layout no seu construtor e obtém referências aos seus elementos internos (findViewById).