Olá pessoal! Neste tutorial vamos simular a execução de uma tarefa em background, atualizando a interface do usuário através de uma barra de progresso. Neste ponto, a aplicação Lista de Restaurantes ainda não tem nenhuma tarefa que demande processamento maciço que justifique tal uso, de forma que este tutorial serve apenas para exemplificar o uso de threads e barras de progresso.
Para começar, em vez de utilizar o widget ProgressBar, vamos utilizar a funcionalidade de barra de progresso da própria Activity. Isso fará com que a barra de progresso apareça junto com o título, fazendo com que não precisemos nos preocupar em encaixá-la no layout. Para que isso aconteça, precisamos adicionar uma linha ao método onCreate(), chamando o método antes do setContentView(). Dessa forma, nosso método onCreate() fica assim:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_PROGRESS); setContentView(R.layout.main); ...
Além disso, vamos adicionar um novo atributo à classe, do tipo int, chamado progresso.
EditText nome = null; EditText endereco = null; EditText anotacoes = null; RadioGroup tipos = null; int progresso;
Continuando, precisamos de um método que faça alguma coisa, pra utilizar a barra de progresso. Para isso, vamos criar o método fazerAlgoDemorado() dentro da classe ListaRestaurantes.
private void fazerAlgoDemorado(final int incremento) { SystemClock.sleep(250); // Pode ser algo mais útil! }
O próximo passo é criar um Runnable na classe ListaRestaurantes que execute fazerAlgoDemorado() algumas vezes. Fica assim:
private Runnable tarefaLonga = new Runnable() { public void run() { for (int i = 0; i < 20; i++) { fazerAlgoDemorado(500); } } };
Com os ciclos executados na tarefaLonga, a duração total será de 5s com 20 execuções.
O próximo passo é ajustarmos alguma forma de disparar essa falsa tarefa em algum ponto. O jeito mais fácil de fazermos isso é adicionando uma opção ao menu, de forma que o usuário possa abrir o menu e selecioná-la. O arquivo de imagem tarefa.png encontra-se junto com o projeto no final do post. Atualize, então, o arquivo opcao.xml:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/anotacao" android:title="Exibir Anotação" android:icon="@drawable/anotacao"/> <item android:id="@+id/rodar" android:title="Executar Tarefa" android:icon="@drawable/tarefa"/> </menu>
Continuando, precisamos vincular a funcionalidade a nossa nova opção do menu. Dessa forma, atualize o método onOptionsItemSelected():
@Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.anotacao) { String mensagem = "Nenhum restaurante selecionado"; if (atual != null) { mensagem = atual.getAnotacoes(); } Toast.makeText(this, mensagem, Toast.LENGTH_LONG).show(); return true; } else if (item.getItemId() == R.id.rodar) { new Thread(tarefaLonga).start(); } return super.onOptionsItemSelected(item); }
Caso você execute a aplicação neste momento, ainda não será possível ver a barra de progresso funcionando, mas já será possível conferir a nova opção em nosso menu:
Agora vamos, de fato, gerenciar a nossa barra de progresso. Primeiramente, atualize o método onOptionsItemSelected() para tornar a barra visível e inicializá-la:
@Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.anotacao) { String mensagem = "Nenhum restaurante selecionado"; if (atual != null) { mensagem = atual.getAnotacoes(); } Toast.makeText(this, mensagem, Toast.LENGTH_LONG).show(); return true; } else if (item.getItemId() == R.id.rodar) { setProgressBarVisibility(true); progresso = 0; new Thread(tarefaLonga).start(); return true; } return super.onOptionsItemSelected(item); }
Agora, atualize o método fazerAlgoDemorado() para que atualize o status da barra a cada passagem por ele:
private void fazerAlgoDemorado(final int incremento) { runOnUiThread(new Runnable() { public void run() { progresso += incremento; setProgress(progresso); } }); SystemClock.sleep(250); // Pode ser algo mais útil! }
Por fim, precisamos ocultar a barra de progresso quando a tarefa for completada. Atualize, então, nossa tarefaLonga:
private Runnable tarefaLonga = new Runnable() { public void run() { for (int i = 0; i < 20; i++) { fazerAlgoDemorado(500); } runOnUiThread(new Runnable() { public void run() { setProgressBarVisibility(false); } }); } };
Pronto! Agora já temos uma barra de progresso que sinaliza o progresso da execução de uma enrolação tarefa.
Se você perdeu alguma coisa ou quiser baixar o projeto, é só clicar aqui.
Até a próxima! 🙂