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:
-
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. -
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>.
-
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).