Tutorial Android #13 – Configurando Preferências

Padrão

Olá novamente pessoal! Estão curtindo a série? Espero que sim! 🙂

Hoje vamos adicionar ao nosso aplicativo Lista de Restaurantes a opção do usuário configurar de que forma deve ocorrer a listagem dos restaurantes (nome, tipo, ordem alfabética, etc.).

Pra começar, vamos criar um arquivo XML que tomará conta das configurações de preferência. Dessa forma, crie o arquivo preferencias.xml e coloque-o em res/xml (a pasta ainda não existe… então crie-a). O conteúdo dele será:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
	<ListPreference
	    android:key="listagem"
	    android:title="Modo de Listagem"
	    android:summary="Escolha o modo de listagem a ser utilizado"
	    android:entries="@array/nomes_ordenacao"
		android:entryValues="@array/opcoes_ordenacao"
		android:dialogTitle="Escolha o modo de listagem" />
</PreferenceScreen>

Em seguida, vamos criar o arquivo arrays.xml que definirá os dois arrays referenciados no XML definido acima. O arquivo arrays.xml deverá ser salvo na pasta res/values. Seu conteúdo é listado a seguir:

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<string-array name="nomes_ordenacao">
	    <item>Por Nome, Ascendente</item>
	    <item>Por Nome, Descendente</item>
	    <item>Por Tipo</item>
	    <item>Por Endereço, Ascendente</item>
	    <item>Por Endereço, Descendente</item>
	</string-array>
	<string-array name="opcoes_ordenacao">
	    <item>nome ASC</item>
	    <item>nome DESC</item>
	    <item>tipo, nome ASC</item>
	    <item>endereco ASC</item>
	    <item>endereco DESC</item>
	</string-array>
</resources>

O próximo passo é a criação da Activity responsável pelas preferências. Vamos criar a classe EdicaoPreferencias, que estenderá PreferenceActivity, dentro do pacote net.rafaeltoledo.restaurante:

package net.rafaeltoledo.restaurante;

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class EdicaoPreferencias extends PreferenceActivity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		addPreferencesFromResource(R.xml.preferencias);
	}
}

Também é necessário atualizar o arquivo AndroidManifest.xml, já que adicionamos uma nova Activity ao nosso projeto.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.rafaeltoledo.restaurante"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".ListaRestaurantes" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".FormularioDetalhes">
        </activity>
        <activity android:name=".EdicaoPreferencias">
        </activity>
    </application>

</manifest>

Continuando, vamos agora vincular a nossa nova Activity ao menu de opções. Primeiramente, vamos editar o arquivo opcao.xml, que se encontra em res/menu.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:id="@+id/adicionar"
	    android:title="Adicionar"
	    android:icon="@drawable/adicionar"/>
	<item android:id="@+id/prefs"
	    android:title="Configurações"
	    android:icon="@drawable/menu_preferencias"/>
</menu>

O ícone referenciado é padrão do sistema e, como mostrado no último post, pode ser encontrado na própria instalação da SDK. Este ícone utilizado se chama ic_menu_preferences (que eu renomeei para menu_preferencias em nosso projeto).

Agora, vamos modificar o método onOptionsItemSelected na classe ListaRestaurantes para mapear esta nova opção adicionada ao menu:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
	if (item.getItemId() == R.id.adicionar) {
		startActivity(new Intent(ListaRestaurantes.this, FormularioDetalhes.class));
		return true;
	} else if (item.getItemId() == R.id.prefs) {
		startActivity(new Intent(this, EdicaoPreferencias.class));
		return true;
	}

	return super.onOptionsItemSelected(item);
}

Neste ponto, se você rodar a aplicação, já poderá conferir o menu:

Agora, já que a parte visual está pronta, vamos aplicar a ordenação a nossa lista. Primeiramente, precisamos que o método obterTodos() da classe GerenciadorRestaurantes precisa receber o método de ordenação por parâmetro e aplicá-lo a SQL. Modifique-o para que fique assim:

public Cursor obterTodos(String ordenacao) {
	return getReadableDatabase().rawQuery("select _id, nome, endereco, tipo, " +
			"anotacoes FROM restaurantes ORDER BY " + ordenacao, null);
}

Agora, precisamos de um atributo na classe ListaRestaurantes que nos permita saber a ordenação selecionada e aplicá-la a listagem. Adicione um atributo à classe chamado prefs do tipo SharedPreferences.

SharedPreferences prefs = null;

Em seguida, adicione a inicialização do atributo no método onCreate(), próximo ao seu início.

prefs = PreferenceManager.getDefaultSharedPreferences(this);

E modifique a chamada ao método obterTodos() logo em seguida:

listaRestaurantes = gerenciador.obterTodos(prefs.getString("ordenacao", "nome"));

Por fim, vamos fazer com que seja aplicada as alterações realizadas pelo usuário em tempo de execução, já que, por enquanto, é necessário fechar a aplicação para que a nova ordenação tenha efeito. Adicione esta linha ao fim do método onCreate():

prefs.registerOnSharedPreferenceChangeListener(prefListener);

Em seguida, vamos criar o listener dentro da classe ListaRestaurantes:

private OnSharedPreferenceChangeListener prefListener = new OnSharedPreferenceChangeListener() {

	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
			String key) {
		if (key.equals("ordenacao")) {

		}
	}
};

Continuando, vamos isolar a inicialização da lista em um método à parte, deixando o método onCreate() mais limpo. Crie o método inicializarLista():

private void inicializarLista() {
	if (listaRestaurantes != null) {
		stopManagingCursor(listaRestaurantes);
		listaRestaurantes.close();
	}

	listaRestaurantes = gerenciador.obterTodos(prefs.getString("listagem", "nome"));
	startManagingCursor(listaRestaurantes);
	adaptador = new AdaptadorRestaurante(listaRestaurantes);
	setListAdapter(adaptador);
}

Agora, referenciamos o recém-criado método inicializarLista() no método onCreate():

@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);

	prefs = PreferenceManager.getDefaultSharedPreferences(this);
	gerenciador = new GerenciadorRestaurantes(this);
	inicializarLista();
	prefs.registerOnSharedPreferenceChangeListener(prefListener);
}

E então, também fazemos uma chamada ao método inicializarLista() dentro do nosso prefListener:

private OnSharedPreferenceChangeListener prefListener = new OnSharedPreferenceChangeListener() {

	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
			String key) {
		if (key.equals("listagem")) {
			inicializarLista();
		}
	}
};

E pronto! Já temos o nosso aplicativo funcionando! 🙂

Se você perdeu alguma coisa ou quiser baixar o projeto, só clicar aqui!

Tá ficando interessante, não? Aguardem que vai ficar mais bacana ainda!

3 comentários sobre “Tutorial Android #13 – Configurando Preferências

  1. anderson xavier

    Parabéns Pela Iniciativa! Somente uma critica construtiva… Testes os codigos antes de por online! Abraços.

  2. Laelson Coutinho

    Olá, muito bem explicado. Eu estou com um problema que penso eu que se encaixe nessa área.

    Trata-se e uma modificação que eu estou fazendo para adicionar efeitos de transição na Touchwiz (launcher da samsung)

    eu ja fiz o que precisava na launcher, e também adicionei as opções e efeitos no aplicativo e configurações (SecSettings2, pra ser mais exato, na configuração do visor/display)
    vou passar abaixo o que eu fiz.

    Em res/xml/display_settings.xml eu adicionei isto:

    ListPreference android:entries=”@array/tw_effect_entries” android:title=”Touchwiz Page Effect” android:key=”tw_page_effect” android:defaultValue=”1″ android:entryValues=”@array/tw_effect_values” />

    Depois adicionei isso em strings.xml

    None
    Cascade
    Outer cube
    Inner Cube
    Carousal
    Plain
    Conveyor
    Card

    1
    2
    3
    4
    5
    6
    7
    8

    Feito isso, compilei o apk, a opção aparece tudo certinho, porém, mesmo selecionando um dos efeitos,
    continua do mesmo jeito (nada muda).

    Suspeito que precise criar um arquivo xml como esse preferences.xml, ou uma classe java. Pode me ajudar com isso?

    Entenda melhor aqui aonde tem todo o processo, inclusive as mudanças da touchwiz

    https://forum.xda-developers.com/showpost.php?p=72583990&postcount=10913

Deixe uma resposta