🎲 P01: Guia Passo a Passo - Dados RPG (D20 Clássico)
Bem-vindo à sua primeira grande missão como desenvolvedor Android! 🚀 Neste projeto de entrada da Fase 1: Fundamentos Legados, vamos construir um Simulador de Dados D20 Clássico.
Se você já jogou RPG de mesa, sabe que o D20 é o dado que decide o seu destino. Aqui, ele vai decidir se o seu código é um sucesso crítico! Você aprenderá as bases mais importantes da plataforma Android: desenhar telas com arquivos XML e controlá-las com a linguagem Java.
✅ Pré-requisitos
Antes de começar, certifique-se de já ter estudado:
- 📘 Cap 01: Seu Primeiro App (Activity, XML e Views)
- 📘 Cap 02: Sorte e Decisão em Java (Variáveis, Operadores e Random)
🎯 Objetivo do Projeto
Criar um app imersivo com uma interface escurecida de Dungeon Master. Ao clicar no botão vermelho “Lançar Sorte”, o app sorteia um número de 1 a 20 e atualiza o marcador central instantaneamente.
graph TD
A[Início / App Aberto] --> B[Clique no Botão 'Lançar Sorte']
B --> C[Executar Ação de Clique]
C --> D[Gerar Número Aleatório de 1 a 20]
D --> E[Converter Número para Texto]
E --> F[Atualizar TextView com setText]
F --> G[Fim / Esperando Próximo Clique]
📖 Dicionário do Projeto
- RelativeLayout: Layout que nos permite posicionar componentes em posições livres (ex: centralizar um item na tela ou alinhar outro perfeitamente ao rodapé).
- LinearLayout: Um layout simples que empilha os componentes um atrás do outro (horizontal) ou um embaixo do outro (vertical).
- TextView: O componente visual básico usado para exibir qualquer tipo de texto na tela do celular.
- Button: Um componente clicável que serve para iniciar alguma ação no código Java do aplicativo.
- findViewById: O método usado em Java para localizar um componente do XML usando o ID correspondente. É a “ponte” entre a tela e o código.
- setOnClickListener: O ouvinte de eventos de clique. É o “ouvido” do botão que fica aguardando o toque do usuário para executar uma função.
- Random: Classe padrão do Java usada para gerar números pseudo-aleatórios.
🛠️ Passo 1: Configurando o Projeto no Android Studio
Antes de codar, precisamos preparar o terreno:
- Abra o Android Studio e clique em
New Project. - Escolha o template Empty Views Activity (Cuidado: não escolha o “Empty Activity” puro, pois ele usa Compose).
- Configure os dados do seu app:
- Name:
Dados RPG - Package Name:
br.com.curso.dadosrpg - Language: Java (O clássico).
- Minimum SDK: API 21 (Android 5.0) ou superior.
- Name:
- Clique em Finish e aguarde o Gradle carregar o projeto completamente.
💡 Este projeto já inclui um
.gitignorede exemplo — copie-o para a raiz do seu projeto antes do primeiro commit (veja a seção “Como Entregar seus Projetos” no índice da trilha).
🎨 Passo 2: Desenhando a Interface (XML)
No Android, o desenho da tela fica em arquivos XML. Desenharemos uma mesa imersiva de RPG com fundo preto e luzes em tons de vermelho neon.
- No painel esquerdo do Android Studio, vá em
app > src > main > res > layout > activity_main.xml. - Clique na aba Code (no topo superior direito) para ver o código de texto.
- Apague o código inicial e cole esta estrutura:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#121212"
android:padding="24dp">
<!-- Decoração de Fundo (Simulando Neon) -->
<View
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
android:background="@android:drawable/screen_background_dark_transparent"
android:alpha="0.1" />
<!-- Título do Jogo -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:text="DUNGEON MASTER"
android:textColor="#FF4444"
android:textSize="14sp"
android:letterSpacing="0.3"
android:textStyle="bold" />
<!-- Container Centralizado do Dado -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical">
<!-- Mostrador do Resultado -->
<TextView
android:id="@+id/txt_resultado"
android:layout_width="180dp"
android:layout_height="180dp"
android:background="@android:drawable/editbox_background_normal"
android:backgroundTint="#1E1E1E"
android:gravity="center"
android:text="20"
android:textColor="#FFFFFF"
android:textSize="90sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="RESULTADO DO D20"
android:textColor="#666666"
android:textSize="12sp" />
</LinearLayout>
<!-- Botão de Ação Alinhado ao Rodapé -->
<Button
android:id="@+id/btn_rolar"
android:layout_width="match_parent"
android:layout_height="65dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:backgroundTint="#FF1C1C"
android:text="LANÇAR SORTE"
android:textColor="#FFFFFF"
android:textSize="18sp"
android:textStyle="bold" />
</RelativeLayout>
🧠 Passo 3: Programando a Lógica de Sorteio (Java)
Agora que a planta física está pronta, vamos ligar a energia no código Java!
- Abra o arquivo
MainActivity.javalocalizado emapp > src > main > java > br.com.curso.dadosrpg > MainActivity.java. - Substitua o conteúdo pelo código dinâmico:
package br.com.curso.dadosrpg;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
// 1. Declaramos as variáveis que representarão nossos componentes visuais
private TextView txtResultado;
private Button btnRolar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // Faz a ligação com o XML
// 2. Fazemos a ponte: O Java localiza os componentes na tela usando os IDs
txtResultado = findViewById(R.id.txt_resultado);
btnRolar = findViewById(R.id.btn_rolar);
// 3. Programamos a ação ao clicar no botão
btnRolar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
rolarDado(); // Chama a nossa função de sorteio
}
});
}
/**
* Sorteia um número de 1 a 20 e atualiza a tela
*/
private void rolarDado() {
// 4. Cria um gerador de números aleatórios
Random gerador = new Random();
// 5. Sorteia um número de 0 a 19 e soma 1 (resultado final: 1 a 20)
int numero = gerador.nextInt(20) + 1;
// 6. Atualiza o texto na tela
// Importante: setText sempre precisa de Texto (String), por isso o String.valueOf
txtResultado.setText(String.valueOf(numero));
}
}
🛠️ Requisitos Críticos de Configuração
1. Suporte ao AndroidX (Evita travamentos de build)
Certifique-se de que o arquivo gradle.properties na raiz do seu projeto possui estas flags essenciais de compatibilidade ativas:
android.useAndroidX=true
android.enableJetifier=true
2. Unidades de Medida corretas no XML (Sem ponto decimal)
Diferente da programação convencional, medidas de dimensões no Android no XML não toleram números flutuantes:
- ❌ Errado:
android:padding="24.5dp" - ✅ Correto:
android:padding="24dp"
📸 Resultado Esperado
Veja como sua tela deve ficar ao final deste projeto:

🏆 Desafios para você (Upgrade!)
Se você terminou de programar a mecânica base do jogo e tudo está funcionando, experimente estes upgrades:
- D6 Alternativo: Tente adicionar um segundo botão na tela para rolar um dado de 6 faces (D6).
- Mudar Cor: Altere o atributo
android:backgroundTintdo botão vermelho no XML para uma cor personalizada de sua preferência.
📖 Gabarito Oficial de Código (Para Conferência)
Use os códigos completos abaixo para validar sua implementação ou corrigir problemas de compilação.
📄 Layout Completo (activity_main.xml)
Disponível em: app/src/main/res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#121212"
android:padding="24dp">
<!-- Decoração de Fundo (Simulando Neon) -->
<View
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
android:background="@android:drawable/screen_background_dark_transparent"
android:alpha="0.1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:text="DUNGEON MASTER"
android:textColor="#FF4444"
android:textSize="14sp"
android:letterSpacing="0.3"
android:textStyle="bold" />
<!-- Container do Dado -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/txt_resultado"
android:layout_width="180dp"
android:layout_height="180dp"
android:background="@android:drawable/editbox_background_normal"
android:backgroundTint="#1E1E1E"
android:gravity="center"
android:text="20"
android:textColor="#FFFFFF"
android:textSize="90sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="RESULTADO DO D20"
android:textColor="#666666"
android:textSize="12sp" />
</LinearLayout>
<!-- Botão Estilizado -->
<Button
android:id="@+id/btn_rolar"
android:layout_width="match_parent"
android:layout_height="65dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:backgroundTint="#FF1C1C"
android:text="LANÇAR SORTE"
android:textColor="#FFFFFF"
android:textSize="18sp"
android:textStyle="bold" />
</RelativeLayout>
📄 Lógica Java Completa (MainActivity.java)
Disponível em: app/src/main/java/br/com/curso/dadosrpg/MainActivity.java
package br.com.curso.dadosrpg;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
// Componentes da Interface
private TextView txtResultado;
private Button btnRolar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Ligando o Java ao XML (IDs)
txtResultado = findViewById(R.id.txt_resultado);
btnRolar = findViewById(R.id.btn_rolar);
// Ação de Clique do Botão
btnRolar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
rolarDado();
}
});
}
/**
* Sorteia um número de 1 a 20 e atualiza a tela
*/
private void rolarDado() {
// Gerador de números aleatórios
Random gerador = new Random();
// Sorteia de 0 a 19 e soma 1 (para ficar de 1 a 20)
int numero = gerador.nextInt(20) + 1;
// Mostra o número no TextView (convertendo int para String)
txtResultado.setText(String.valueOf(numero));
}
}