Tutorial Android #8 – Barras de Progresso

Padrão

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<br />
public void onCreate(Bundle savedInstanceState) {<br />
	super.onCreate(savedInstanceState);<br />
	requestWindowFeature(Window.FEATURE_PROGRESS);<br />
	setContentView(R.layout.main);<br />
	...

Além disso, vamos adicionar um novo atributo à classe, do tipo int, chamado progresso.

EditText nome = null;<br />
EditText endereco = null;<br />
EditText anotacoes = null;<br />
RadioGroup tipos = null;<br />
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) {<br />
	SystemClock.sleep(250); // Pode ser algo mais útil!<br />
}

O próximo passo é criar um Runnable na classe ListaRestaurantes que execute fazerAlgoDemorado() algumas vezes. Fica assim:

private Runnable tarefaLonga = new Runnable() {<br />
	public void run() {<br />
		for (int i = 0; i &lt; 20; i++) {<br />
			fazerAlgoDemorado(500);<br />
		}<br />
	}<br />
};

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:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br />
&lt;menu xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&gt;<br />
	&lt;item android:id=&quot;@+id/anotacao&quot;<br />
	    android:title=&quot;Exibir Anotação&quot;<br />
	    android:icon=&quot;@drawable/anotacao&quot;/&gt;<br />
	&lt;item android:id=&quot;@+id/rodar&quot;<br />
	    android:title=&quot;Executar Tarefa&quot;<br />
	    android:icon=&quot;@drawable/tarefa&quot;/&gt;<br />
&lt;/menu&gt;

Continuando, precisamos vincular a funcionalidade a nossa nova opção do menu. Dessa forma, atualize o método onOptionsItemSelected():

@Override<br />
public boolean onOptionsItemSelected(MenuItem item) {<br />
	if (item.getItemId() == R.id.anotacao) {<br />
		String mensagem = &quot;Nenhum restaurante selecionado&quot;;</p>
<p>		if (atual != null) {<br />
			mensagem = atual.getAnotacoes();<br />
		}</p>
<p>		Toast.makeText(this, mensagem, Toast.LENGTH_LONG).show();</p>
<p>		return true;<br />
	} else if (item.getItemId() == R.id.rodar) {<br />
		new Thread(tarefaLonga).start();<br />
	}</p>
<p>	return super.onOptionsItemSelected(item);<br />
}

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<br />
public boolean onOptionsItemSelected(MenuItem item) {<br />
	if (item.getItemId() == R.id.anotacao) {<br />
		String mensagem = &quot;Nenhum restaurante selecionado&quot;;</p>
<p>		if (atual != null) {<br />
			mensagem = atual.getAnotacoes();<br />
		}</p>
<p>		Toast.makeText(this, mensagem, Toast.LENGTH_LONG).show();</p>
<p>		return true;<br />
	} else if (item.getItemId() == R.id.rodar) {<br />
		setProgressBarVisibility(true);<br />
		progresso = 0;<br />
		new Thread(tarefaLonga).start();</p>
<p>		return true;<br />
	}</p>
<p>	return super.onOptionsItemSelected(item);<br />
}

Agora, atualize o método fazerAlgoDemorado() para que atualize o status da barra a cada passagem por ele:

private void fazerAlgoDemorado(final int incremento) {<br />
	runOnUiThread(new Runnable() {<br />
		public void run() {<br />
			progresso += incremento;<br />
			setProgress(progresso);<br />
		}<br />
	});</p>
<p>	SystemClock.sleep(250); // Pode ser algo mais útil!<br />
}

Por fim, precisamos ocultar a barra de progresso quando a tarefa for completada. Atualize, então, nossa tarefaLonga:

private Runnable tarefaLonga = new Runnable() {<br />
	public void run() {<br />
		for (int i = 0; i &lt; 20; i++) {<br />
			fazerAlgoDemorado(500);<br />
		}</p>
<p>		runOnUiThread(new Runnable() {<br />
			public void run() {<br />
				setProgressBarVisibility(false);<br />
			}<br />
		});<br />
	}<br />
};

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! 🙂