Hello again folks! Are you enjoying the show? Hope so!
Today we will add to our Restaurant List application the user's option to configure how restaurant listings ( name , type , alphabetical order , etc.) should occur .
To begin, let's create an XML file that will take care of preference settings. That way, create the preferences.xml file and put it in res / xml (the folder does not exist yet ... so create it). The content of it will be:
1
2
3
4
5
6
7
8
9
| < 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 > |
Next, let's create the arrays.xml file that will define the two arrays referenced in the XML defined above. The file arrays.xml should be saved in the res / values folder . Its contents are listed below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| <? 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 > |
The next step is to create the Activity that is responsible for preferences. Let's create the class EdicaoPreferencias , which will extend PreferenceActivity , inside the package net.rafaeltoledo.restaurante :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| 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); } } |
You also need to update the AndroidManifest.xml file , since we've added a new Activityto our project.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| <? xml version = "1.0" encoding = "utf-8" ?> 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 > |
Continuing, let's now link our new Activity to the options menu. First, let's edit the file opcao.xml , which is in the / menu .
1
2
3
4
5
6
7
8
9
| <? xml version = "1.0" encoding = "utf-8" ?> < 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 > |
The referenced icon is system default and, as shown in the last post, can be found in the SDK installation itself. This icon is called ic_menu_preferences (which I renamed to menu_preferencias in our project).
Now, let's modify the onOptionsItemSelected method in the RestaurantList class to map this new option added to the menu:
58
59
60
61
62
63
64
65
66
67
68
69
| @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); } |
At this point, if you run the application, you can check the menu:
Now, since the visual part is ready, let's apply the sort to our list. First, we need the method obterTodos () class GerenciadorRestaurantes must receive the ordering method for parameter and apply it to SQL. Modify it to look like this:
52
53
54
55
| public Cursor obterTodos(String ordenacao) { return getReadableDatabase().rawQuery( "select _id, nome, endereco, tipo, " + "anotacoes FROM restaurantes ORDER BY " + ordenacao, null ); } |
Now, we need an attribute in theResourcesList class that allows us to know the sortedordering and apply it to the listing. Add an attribute to the class called prefs of type SharedPreferences .
26
| SharedPreferences prefs = null ; |
Then, add the initialization of the attribute in the onCreate () method , near its onset.
34
| prefs = PreferenceManager.getDefaultSharedPreferences( this ); |
And modify the call to the get method () immediately after:
36
| listaRestaurantes = gerenciador.obterTodos(prefs.getString( "ordenacao" , "nome" )); |
Finally, let's apply the changes made by the user at run time, as, for now, it is necessary to close the application for the new ordering to take effect. Add this line to the end of the onCreate () method :
40
| prefs.registerOnSharedPreferenceChangeListener(prefListener); |
Next, let's create the listener inside the class ListRestaurants :
1
2
3
4
5
6
7
8
9
| private OnSharedPreferenceChangeListener prefListener = new OnSharedPreferenceChangeListener() { public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (key.equals( "ordenacao" )) { } } }; |
Continuing, let's isolate the initialization of the list in a separate method, leaving the onCreate () method cleaner. Create the Start () method :
77
78
79
80
81
82
83
84
85
86
87
| 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); } |
Now, we reference the newly created initializeList () method in the onCreate () method :
30
31
32
33
34
35
36
37
38
39
| @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); } |
And then we also make a call to the initializeList () method inside our prefListener :
86
87
88
89
90
91
92
93
94
| private OnSharedPreferenceChangeListener prefListener = new OnSharedPreferenceChangeListener() { public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (key.equals( "listagem" )) { inicializarLista(); } } }; |
And ready! We already have our application running!
It's getting interesting, is not it? Wait, it's going to be even cooler!