Componentes Básicos do Android: TextViews, Layouts e Interatividade

Exibição de Texto

Definição do Conteúdo Textual

Existem três abordagens principais para definir o conteúdo de um TextView:

  1. Valor literal diretamente no XML
  2. Valor definido programaticamente em tempo de execução
  3. Referência a recursos externos no arquivo strings.xml

Exemplo prático com as três abordagens:

Arquivo de layout (res/layout/activity_main.xml):

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/txtDireto"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Texto direto no XML" />

    <TextView
        android:id="@+id/txtRecurso"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/label_recurso" />

    <TextView
        android:id="@+id/txtDinamico"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</androidx.constraintlayout.widget.ConstraintLayout>

Arquivo de recursos (res/values/strings.xml):

<resources>
    <string name="app_name">Minha Aplicação</string>
    <string name="label_recurso">Texto do recurso</string>
    <string name="label_codigo">Texto via código</string>
</resources>

Classe da Activity:

public class MainActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        TextView dinamico = findViewById(R.id.txtDinamico);
        dinamico.setText("Definido em tempo de execução");
        
        // Também é possível usar recurso de string
        // dinamico.setText(R.string.label_codigo);
    }
}

Referências comuns:

  • No XML: @string/nome_recurso
  • No Java/Kotlin: R.string.nome_recurso

Unidades de Tamanho de Texto

Três unidades fundamentais para dimensionamento:

Unidade Descrição
px (pixels) Unidade absoluta vinculada à densidade física da tela. Não recomendada para interfaces responsivas.
dp/dip (density-independent pixels) Unidade relativa à densidade da tela. Garante consistência visual em diferentes dispositivos.
sp (scalable pixels) Similar ao dp, mas respeita as preferências de acessibilidade do usuário para tamanho de fonte.

Demonstração comparativa:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/exemploPx"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24px"
        android:text="24 pixels" />

    <TextView
        android:id="@+id/exemploDp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24dp"
        android:text="24 dp" />

    <TextView
        android:id="@+id/exemploSp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="24 sp (padrão)" />

</LinearLayout>
// Configurando via código - método setTextSize usa SP por padrão
TextView exemploSp = findViewById(R.id.exemploSp);
exemploSp.setTextSize(24); // automaticamente interpretado como sp

Personalização de Cores

Atributos principais para coloração:

  • android:textColor: cor do texto
  • android:background: cor de fundo do componente

Exemplo de aplicação:

<TextView
    android:id="@+id/txtEstilizado"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Texto colorido"
    android:textColor="#FFFFFF"
    android:background="#6200EE" />
TextView estilizado = findViewById(R.id.txtEstilizado);
estilizado.setTextColor(Color.parseColor("#FF5722"));
estilizado.setBackgroundColor(Color.argb(255, 33, 150, 243));

Fundamentos de Views

Dimensões de Componentes

Os atributos android:layout_width e android:layout_height aceitam:

Valor Comportamento
match_parent Preenche completamente o espaço disponível no container pai
wrap_content Ajusta-se ao tamanho mínimo necessário para exibir o conteúdo
valor em dp Dimensão fixa específica (ex: 120dp)

Alteração programática de dimensões:

View componente = findViewById(R.id.meuComponente);
ViewGroup.LayoutParams parametros = componente.getLayoutParams();
parametros.width = 300; // em pixels, converter de dp se necessário
parametros.height = ViewGroup.LayoutParams.WRAP_CONTENT;
componente.setLayoutParams(parametros);

Espaçamento e Alinhamento

Margens externas (distância entre componentes irmãos):

  • android:layout_margin (todas as direções)
  • android:layout_marginStart, android:layout_marginEnd
  • android:layout_marginTop, android:layout_marginBottom

Preenchimento interno (distância entre borda e conteúdo):

  • android:padding (todas as direções)
  • android:paddingHorizontal, android:paddingVertical
  • android:paddingStart, android:paddingEnd, etc.

Propriedades de gravidade:

  • android:layout_gravity: posicionamento do componente dentro do container
  • android:gravity: alinhamento do conteúdo dentro do próprio componente

Valores combináveis com |: center, top, bottom, start, end, center_vertical, center_horizontal

Tipos de Layout

LinearLayout

Organiza componentes em sequência única, controlada por android:orientation:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- Seção horizontal embutida -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="#E3F2FD">
        
        <Button android:layout_width="wrap_content" 
                android:layout_height="wrap_content"
                android:text="A" />
        <Button android:layout_width="wrap_content" 
                android:layout_height="wrap_content"
                android:text="B" />
    </LinearLayout>

    <!-- Continuação vertical -->
    <TextView android:layout_width="wrap_content" 
              android:layout_height="wrap_content"
              android:text="Item 1" />
    <TextView android:layout_width="wrap_content" 
              android:layout_height="wrap_content"
              android:text="Item 2" />

</LinearLayout>

ConstraintLayout

Layout flexível baseado em restrições entre componentes:

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/centro"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Centralizado"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Acima"
        app:layout_constraintBottom_toTopOf="@id/centro"
        app:layout_constraintStart_toStartOf="@id/centro" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="À direita"
        app:layout_constraintStart_toEndOf="@id/centro"
        app:layout_constraintTop_toTopOf="@id/centro" />

</androidx.constraintlayout.widget.ConstraintLayout>

GridLayout

Distribuição em células de grade:

<GridLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnCount="3"
    android:rowCount="2"
    android:useDefaultMargins="true">

    <Button android:text="1,1" />
    <Button android:text="1,2" />
    <Button android:text="1,3" />
    <Button android:text="2,1" />
    <Button android:text="2,2" />
    <Button android:text="2,3" />

</GridLayout>

ScrollView e HorizontalScrollView

Containers para conteúdo que excede as dimensões visíveis:

<!-- Rolagem vertical -->
<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        
        <!-- Múltiplos itens que ultrapassam a altura da tela -->
        <ImageView android:layout_width="match_parent" 
                   android:layout_height="400dp"
                   android:src="@drawable/imagem_grande" />
        <TextView android:layout_width="match_parent" 
                  android:layout_height="wrap_content"
                  android:text="Conteúdo extenso..." />
        
    </LinearLayout>
</ScrollView>

<!-- Rolagem horizontal -->
<HorizontalScrollView
    android:layout_width="match_parent"
    android:layout_height="120dp">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="horizontal">
        
        <!-- Itens dispostos lateralmente -->
        <CardView ... />
        <CardView ... />
        <CardView ... />
        
    </LinearLayout>
</HorizontalScrollView>

Restrição importante: ScrollView aceita apenas um filho direto. Use um layout container como wrapper quanndo necessário.

Interatividade com Botões

Propriedades do Button

Atributo Função
android:textAllCaps Converte texto para maiúsculas (true padrão)
android:enabled Ativa/desativa interatividade
android:onClick Método de calback via atributo XML (legado)

Tratamento de Eventos

Abordagem com expressão lambda:

public class ControleActivity extends AppCompatActivity {
    
    private TextView visorResultado;
    private Button btnAcao, btnAtivar, btnDesativar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.controle_layout);
        
        vincularComponentes();
        configurarOuvintes();
    }

    private void vincularComponentes() {
        visorResultado = findViewById(R.id.txtResultado);
        btnAcao = findViewById(R.id.btnExecutar);
        btnAtivar = findViewById(R.id.btnAtivar);
        btnDesativar = findViewById(R.id.btnDesativar);
    }

    private void configurarOuvintes() {
        btnAtivar.setOnClickListener(v -> btnAcao.setEnabled(true));
        btnDesativar.setOnClickListener(v -> btnAcao.setEnabled(false));
        
        btnAcao.setOnClickListener(v -> {
            String momentoAtual = LocalDateTime.now()
                .format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"));
            visorResultado.setText(momentoAtual);
        });
    }
}

Implemetnação de interface compartilhada:

public class PainelActivity extends AppCompatActivity 
        implements View.OnClickListener {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.painel_layout);
        
        findViewById(R.id.botaoSalvar).setOnClickListener(this);
        findViewById(R.id.botaoCancelar).setOnClickListener(this);
        findViewById(R.id.botaoExcluir).setOnClickListener(this);
    }

    @Override
    public void onClick(View origem) {
        int identificador = origem.getId();
        
        if (identificador == R.id.botaoSalvar) {
            persistirDados();
        } else if (identificador == R.id.botaoCancelar) {
            descartarAlteracoes();
        } else if (identificador == R.id.botaoExcluir) {
            confirmarExclusao();
        }
    }
}

Exibição de Imagens

ImageView

Componente para apresentação visual:

<ImageView
    android:id="@+id/visualizadorFoto"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:src="@drawable/paisagem"
    android:scaleType="centerCrop"
    android:contentDescription="@string/descricao_paisagem" />
ImageView visualizador = findViewById(R.id.visualizadorFoto);
visualizador.setImageResource(R.drawable.paisagem);
visualizador.setScaleType(ImageView.ScaleType.FIT_CENTER);

Modos de escala disponíveis:

Modo Comportamento
centerCrop Preenche completamente, mantendo proporção (corta excesso)
fitCenter Encaixa inteiramente, mantendo proporção (pode haver área vazia)
centerInside Similar a fitCenter, mas sem expansão além do tamanho original
fitXY Estica para preencher, pode distorcer a imagem
center Centraliza sem escala

ImageButton

Variante interativa do ImageView:

<ImageButton
    android:id="@+id/btnCamera"
    android:layout_width="64dp"
    android:layout_height="64dp"
    android:src="@drawable/ic_camera"
    android:background="?attr/selectableItemBackgroundBorderless"
    android:contentDescription="@string/acessar_camera" />

Botão com Texto e Ícone

O componente Button suporta ícones posicionados relativamente ao texto:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Compartilhar"
    android:drawableStart="@drawable/ic_share"
    android:drawablePadding="8dp"
    android:drawableTint="@color/branco" />

Atributos de posicionamento do ícone:

  • drawableStart / drawableEnd: ícone à esquerda/direita do texto
  • drawableTop / drawableBottom: ícone acima/abaixo do texto
  • drawablePadding: espaçamento entre ícone e texto

Tags: android textview LinearLayout ConstraintLayout GridLayout

Publicado em 9-19 15:43