Android - Adicionando e mostrando itens ao ListView um de cada vez usando um Arrayadapter
-
22-09-2019 - |
Pergunta
Estou usando um ArrayAdapter para adicionar itens a um ListView personalizado e mostrando os resultados no meu aplicativo Android. O problema que estou tendo é que o Arrayadapter parece esperar até que todos os itens estejam nele antes de mostrar a visualização. Ou seja, quando estou adicionando os itens ao ArrayAdapter e chamo o NotifyDataSetchanged, ele não atualiza o ListView para mostrar o item adicionado. Ele espera até que todos os itens sejam adicionados e o getView seja chamado antes de mostrar os itens.
O que eu gostaria que ele faça é mostrar o item imediatamente após adicioná -lo ao ListView. Isso é possível?
Eu acredito que o código relevante é o seguinte:
r_adapter = new ReminderAdapater(Activity_ContentSearch.this, R.layout.search_listitem, myList);
listView.setAdapter(r_adapter);
...
r_adapter.notifyDataSetChanged();
r_adapter.clear();
for(int i = 0; i < myList.size(); i++)
{
r_adapter.add(myList.get(i));
r_adapter.notifyDataSetChanged();
}
Como você pode ver, mesmo que eu esteja ligando para o NotifyDataSetchanged após o método ADD, ele não atualiza a visualização. Depois de terminar o loop acima, a exibição é finalmente atualizada (com base no que sei, porque o getView não é chamado até que esta seção do código seja concluída).
Tentei substituir o método ADD do meu ArrayAdapter personalizado sem sorte, já que não tenho acesso à exibição nesse método.
Qualquer ajuda é bem vinda :)
Bara
Solução
A interface do usuário do Android é um único thread. Você não está devolvendo o controle ao Android a partir do encadeamento principal do aplicativo sempre que adicionar uma entrada ao adaptador. Portanto, o Android não tem a chance de exibir suas entradas até que você retorne o controle, e você não está fazendo isso até que tenha preenchido seu adaptador na íntegra.
Aqui está um exemplo mostrando o uso de um AsyncTask
Para preencher um ArrayAdapter
progressivamente através de um tópico de segundo plano.
/***
Copyright (c) 2008-2012 CommonsWare, LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
From _The Busy Coder's Guide to Android Development_
http://commonsware.com/Android
*/
package com.commonsware.android.async;
import android.app.ListActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import java.util.ArrayList;
public class AsyncDemo extends ListActivity {
private static final String[] items={"lorem", "ipsum", "dolor",
"sit", "amet", "consectetuer",
"adipiscing", "elit", "morbi",
"vel", "ligula", "vitae",
"arcu", "aliquet", "mollis",
"etiam", "vel", "erat",
"placerat", "ante",
"porttitor", "sodales",
"pellentesque", "augue",
"purus"};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
new ArrayList<String>()));
new AddStringTask().execute();
}
class AddStringTask extends AsyncTask<Void, String, Void> {
@Override
protected Void doInBackground(Void... unused) {
for (String item : items) {
publishProgress(item);
SystemClock.sleep(200);
}
return(null);
}
@SuppressWarnings("unchecked")
@Override
protected void onProgressUpdate(String... item) {
((ArrayAdapter<String>)getListAdapter()).add(item[0]);
}
@Override
protected void onPostExecute(Void unused) {
Toast
.makeText(AsyncDemo.this, "Done!", Toast.LENGTH_SHORT)
.show();
}
}
}