Chegaram 4 novos estagiários aqui no projeto e coube "a minha pessoa" orientá-los. Durante a aula, o assunto enveredou para tratamento de mudança de orientação do aparelho (portrait e landscape | retrato e paisagem).
Por padrão, ao girar o telefone o método onCreate é chamado novamente e com isso, dados que foram carregados dinamicamente (como itens de um ArrayList que estão preenchendo um ListView) são perdidos.
Vejamos o exemplo abaixo:
Arquivo de layout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:background="#0000FF"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Digite o nome" /> <EditText android:id="@+id/editText1" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="meuBotaoClick" android:text="Adicionar" /> <ListView android:id="@+id/listView1" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
Classe da Activity
public class TelaPrincipalActivity
extends Activity {
EditText edt;
ArrayList<String> nomes;
ArrayAdapter<String> adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
edt = (EditText) findViewById(R.id.editText1);
ListView listView = (ListView)
findViewById(R.id.listView1);
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, nomes);
listView.setAdapter(adapter);
}
public void meuBotaoClick(View v) {
nomes.add(edt.getText().toString());
edt.setText("");
adapter.notifyDataSetChanged();
}
}
No código acima, ao clicar no botão, o texto digitado no EditText é inserido na lista, e em seguida o adapter é atualizado através do método notifyDataSetChanged.
O exemplo é bem simples, mas se você girarmos o aparelho os dados que estão sendo exibidos são perdidos, uma vez que a lista inicia vazia e (como já falei) o onCreate é chamado novamente.
Para isso não acontecer você tem 3 alternativas:
1)Forçar uma orientação
Na declaração da sua Activity, no AndroidManifest.xml, você pode usar a propriedade android:screenOrientation para manter sua aplicação em uma orientação específica (portrait/landscape).
<activity android:name="TelaPrincipalActivity" android:screenOrientation="portrait" />
2)Avisar o Android para não chamar o onCreate
Essa é a melhor opção quando você quer utilizar a tela nas duas orientações e impedir que o Android chame o onCreate cada vez que você girar o aparelho. Para isso basta dizer que ao mudar a configuração (configChanges) de orientação, ele não recrie a Activity.
<activity android:name="TelaPrincipalActivity" android:configChanges="orientation|keyboardHidden|screenSize"/>
3) Salvar o estado da Activity
A opção número dois é perfeita quando você quer usar o mesmo layout nas duas orientações. Mas, e se eu quiser usar layouts diferentes? Neste caso você dever permitir que a Activity seja recriada. Entretanto, devemos salvar seu estado com o método onSaveInstanceState e no onCreate recuperar esse estado.
No exemplo que fiz os "estags", criei a pasta "layout-land" com o mesmo layout definido acima, só mudando o background (apenas para notarmos os diferentes layouts). Depois implementamos o método onSaveInstanceState para salvar os itens da lista.
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList("nomes", nomes);
}
Se vocês notaram, o método onSaveInstanceState usa um objeto da classe Bundle para salvar o estado. Esse estado é passado para o método onCreate da Activity como parâmetro, que utilizaremos para restaurar o seu estado.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Código já apresentado
if (savedInstanceState != null) {
nomes = savedInstanceState.
getStringArrayList("nomes");
} else {
nomes = new ArrayList<String>();
}
}
Com isso podemos ter, para a mesma tela, um layout diferente para cada orientação, desde que tenhamos os mesmos componentes (e com os mesmos ids).
Ficou com dúvida? Deixe seu comentário.
4br4ç05,
nglauber






