Como Usar uma Figura de Fundo em uma Tela com ListView no Android

Por padrão o Android apresenta a tela com cor de fundo escuro, e a maioria dos widgets possuem cor de fundo transparente. O widget ListView obedece a mesma regra, normalmente sendo utilizado em uma tela com cor de fundo sólida ou transparente. Caso seja utilizado em uma tela com cor de fundo diferente de uma cor sólida, como por exemplo usando uma figura, é necessário tomar um certo cuidado no projeto, para que o ListView no momento do scroll não apresente um fundo escuro no meio da figura.

Este post descreve como exibir uma figura de fundo em uma tela com ListView e como corrigir o problema ocasionado durante o scroll do ListView. Observe na figura abaixo uma tela com ListView e uma figura de fundo mostrando o efeito do scroll. A figura da esquerda mostra a tela exibida na iniciação da aplicação e a figura da direita mostra a tela no momento é quem é feito o scroll.

imagem1

Na figura onde é feito o scroll podemos observar que a figura deixa de ser exibida corretamente. Isto ocorre devido a uma otimização de exibição de tela no sistema do Android. Para solucionar este problema, no framework do Android foi criado o método setCacheColorHint(int) que pode ser configurado via código, ou podemos utilizar o atributo android:cacheColorHint no arquivo XML do layout.

Para demonstrar a utilização do ListView com figura de fundo foi criado um projeto para exibir a relação de estados do Brasil em um ListView cuja figura de fundo é o mapa do Brasil.

Para exibir a figura de fundo foi criado um arquivo theme.xml na pasta res/values que configura a figura de fundo na janela do Android.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Imagem de fundo da tela do listview -->
    <style name="MapBackground" parent="android:Theme">
        <item name="android:windowBackground">@drawable/mapa</item>
        <item name="android:windowNoTitle">true</item> 
    </style>
</resources>


Observe que foi criada a tag <style> com o nome MapBackground, e a janela do Android foi configurada com a figura do mapa através da tag:

<item name="android:windowBackground">@drawable/mapa</item>

Também foi configurado para que a janela não exiba título, através da tag:

<item name="android:windowNoTitle">true</item>

O tema deve ser aplicado na Activity que vai exibir o ListView. Esta configuração pode ser feita no arquivo AndroidManifest.xml.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="br.com.romar"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Main"
                  android:label="@string/app_name"
                  android:theme="@style/MapBackground">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
    </application>
    <uses-sdk android:minSdkVersion="8" />
 
</manifest> 


No arquivo AndroidManifest.xml na tag <activity> da tela de iniciação (.Main) foi inserido o atributo android:theme="@style/MapBackground" que configura o tema da Activity para exibir a figura do mapa.

No arquivo Main.java no método OnCreate foi inserido o código para exibição dos estados no ListView e a configuração do ListView para corrigir o efeito do scroll.

public class Main extends ListActivity {
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        // Obtêm a relação de estados que está armazenado
        // no arquivo strings.xml
        String[] states = getResources().getStringArray(
                R.array.state_array);
        
        // Preenche o ListView com os estados
        setListAdapter(new ArrayAdapter<String>(this, 
                android.R.layout.simple_list_item_1, states));
        
        // Obtêm o ListView
        ListView lv = getListView();
        // Configurando o método setCacheColorHint para 
        // o valor 0 informamos que a cor de fundo do listview
        // possui não possui cor única, sólida ou opaca
        lv.setCacheColorHint(0);
    }
}


No método onCreate(Bundle savedInstanceState) foi utilizado como fonte de dados um array chamado state_array, configurado no arquivo strings.xml localizado na pasta res/values.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">ListViewI</string>
    <string-array name="state_array">
        <item>Acre</item>
        <item>Alagoas</item>
        <item>Amapá</item>
        <item>Amazonas</item>
        <item>Bahia</item>
        <item>Ceará</item>
        <item>Distrito Federal</item>
        <item>Espírito Santo</item>
        <item>Goiás</item>
        <item>Maranhão</item>
        <item>Mato Grosso</item>
        <item>Mato Grosso do Sul</item>
        <item>Minas Gerais</item>
        <item>Pará</item>
        <item>Paraíba</item>
        <item>Paraná</item>
        <item>Pernambuco</item>
        <item>Piauí</item>
        <item>Rio de Janeiro</item>
        <item>Rio Grande do Norte</item>
        <item>Rio Grande do Sul</item>
        <item>Rondônia</item>
        <item>Roraima</item>
        <item>Santa Catarina</item>
        <item>São Paulo</item>
        <item>Sergipe</item>
        <item>Tocatins</item>
    </string-array>
</resources>


Para exibir o ListView foi utilizado o layout padrão do sistema Android, simple_list_item_1, configurado no método setListAdapter().

Após criado o ListView, foi utilizado o método getListView()  para obter o ListView da Activity e  poder desabilitar a otimização da tela através do método setCacheColorHint(). O valor utilizado foi 0 que representa cor de fundo transparente.

Com a inserção do método setCacheColorHint() o scroll pode ser feito normalmente sem apresentar o defeito na figura de fundo.

Posts Relacionados: