如何动态刷新 ListView? [复制]
Posted
技术标签:
【中文标题】如何动态刷新 ListView? [复制]【英文标题】:How to refresh a ListView dynamically? [duplicate] 【发布时间】:2013-09-16 03:03:38 【问题描述】:我正在尝试实现刷新动态值的 ListAdapter。如果我不需要从互联网连接中获取值(我的情况),这不是一个大问题。
为此,我在适配器中实现了一个 AsyncTask 内部类,但屏幕值的更新不起作用。所有过程都执行没有错误,但屏幕上的信息没有改变。
下面是关于我的代码的一些cmets:
我的 getView 方法被执行并调用 ConsultaPrevisaoBackGround (我的 AsyncTask) 来查询来自互联网的值,他在 getView 方法的末尾执行。
在 AsyncTask 类中,我从 Internet 获取值,并在 onPostExecuteMethod 中调用方法来刷新我的持有者(用于封装小部件的类)。它工作正常(正在运行),但不会反映在屏幕信息中。其实有时候更新屏幕有时候不更新。
我的疑惑是:
1 - 我的策略正确吗?如果是,错误在哪里? 2 - 我可以做些什么来执行这个过程一次,而不是每次用户滚动屏幕时都执行?
我在这方面工作了很长时间,但找不到解决方案...求助!!
package br.com.teste.adapters;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
import android.content.Context;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import br.com.teste.beans.horarios.Estimativa;
import br.com.teste.beans.horarios.Previsao;
import br.com.teste.beans.linhas.Linha;
import br.com.teste.R;
import br.com.teste.util.PrevisaoUtil;
public class ListaLinhasAdapter extends BaseAdapter
private Context context;
private List<Linha> linhas;
private String pontoId;
private LayoutInflater inflater;
private ViewHolder holder;
private String idLinha;
private Previsao p;
public ListaLinhasAdapter(Context context, List<Linha> listaLinhas,
String pontoID)
this.context = context;
this.linhas = listaLinhas;
this.pontoId = pontoID;
this.inflater = LayoutInflater.from(context);
@Override
public int getCount()
return linhas.size();
@Override
public Object getItem(int position)
return linhas.get(position);
@Override
public long getItemId(int position)
return position;
@Override
public View getView(int position, View view, ViewGroup parent)
// Recupera o estado da posição atual
Linha linha = linhas.get(position);
if (view == null)
view = inflater.inflate(R.layout.listadadoslinhas, null);
holder = new ViewHolder(context);
// Número da linha
holder.txtIdLinha = (TextView) view.findViewById(R.id.txtIdLinha);
// Nome da linha
holder.txtNomeLinha = (TextView) view
.findViewById(R.id.txtNomeLinha);
// Seta campo de informação sem parada
holder.txtMsgSemParada = (TextView) view
.findViewById(R.id.msgSemParada);
// seta layouts de previsão
holder.llLinha1 = (LinearLayout) view
.findViewById(R.id.linearPrevisoes1);
holder.llLinha2 = (LinearLayout) view
.findViewById(R.id.linearPrevisoes2);
holder.llLinha3 = (LinearLayout) view
.findViewById(R.id.linearPrevisoes3);
// Seta campos de previsão
holder.txtPrev1 = (TextView) view.findViewById(R.id.txtPrev1);
holder.txtPrev2 = (TextView) view.findViewById(R.id.txtPrev2);
holder.txtPrev3 = (TextView) view.findViewById(R.id.txtPrev3);
holder.txtPrev4 = (TextView) view.findViewById(R.id.txtPrev4);
holder.txtPrev5 = (TextView) view.findViewById(R.id.txtPrev5);
holder.txtPrev6 = (TextView) view.findViewById(R.id.txtPrev5);
view.setTag(holder);
else
holder = (ViewHolder) view.getTag();
holder.reset();
String lin = linha.getLinha().trim();
StringTokenizer stk = new StringTokenizer(lin, "-");
// Número da linha
idLinha = stk.nextToken();
holder.txtIdLinha.setText(idLinha);
// Nome da linha
holder.txtNomeLinha.setText(stk.nextToken());
new ConsultaPrevisaoBackGround().execute("");
return view;
static class ViewHolder
Context context;
TextView txtIdLinha;
TextView txtNomeLinha;
TextView txtMsgSemParada;
LinearLayout llLinha1;
LinearLayout llLinha2;
LinearLayout llLinha3;
TextView txtPrev1;
TextView txtPrev2;
TextView txtPrev3;
TextView txtPrev4;
TextView txtPrev5;
TextView txtPrev6;
public ViewHolder(Context cont)
this.context = cont;
public void reset()
txtIdLinha.setText(null);
txtNomeLinha.setText(null);
limpaPrevisoes();
//Clear fields
private void limpaPrevisoes()
llLinha1.setVisibility(View.GONE);
llLinha2.setVisibility(View.GONE);
llLinha3.setVisibility(View.GONE);
txtMsgSemParada.setVisibility(View.GONE);
txtPrev1.setText(null);
txtPrev2.setText(null);
txtPrev3.setText(null);
txtPrev4.setText(null);
txtPrev5.setText(null);
txtPrev6.setText(null);
//Show message error in textview
public void showError()
showMsg(context.getResources().getString(R.string.msgErroPrevisao));
public void showMsg(String msg)
limpaPrevisoes();
txtMsgSemParada.setText(msg);
public void fillPrevisao(Previsao p)
Collections.sort(p.getPonto());
if (p.getPonto().size() > 6)
// get only first 6 occurs
for (int i = 6; i < p.getPonto().size(); i++)
p.getPonto().remove(i);
int cont = 1;
for (Estimativa estimativa : p.getPonto())
setPrevisao(cont, estimativa, p);
cont++;
if (p.getPonto().size() <= 2)
llLinha2.setVisibility(View.GONE);
llLinha3.setVisibility(View.GONE);
if ((p.getPonto().size() > 2) && (p.getPonto().size() <= 4))
llLinha3.setVisibility(View.GONE);
// Preenche o campo referente à estimativa
private void setPrevisao(int id, Estimativa estimativa,
Previsao previsao)
switch (id)
case 1:
txtPrev1.setText(getPrevisaoFormatada(previsao, estimativa));
setBackGroundColor(estimativa, txtPrev1);
break;
case 2:
txtPrev2.setText(getPrevisaoFormatada(previsao, estimativa));
setBackGroundColor(estimativa, txtPrev2);
break;
case 3:
txtPrev3.setText(getPrevisaoFormatada(previsao, estimativa));
setBackGroundColor(estimativa, txtPrev3);
break;
case 4:
txtPrev4.setText(getPrevisaoFormatada(previsao, estimativa));
setBackGroundColor(estimativa, txtPrev4);
break;
case 5:
txtPrev5.setText(getPrevisaoFormatada(previsao, estimativa));
setBackGroundColor(estimativa, txtPrev5);
break;
case 6:
txtPrev6.setText(getPrevisaoFormatada(previsao, estimativa));
setBackGroundColor(estimativa, txtPrev6);
break;
default:
break;
private String getPrevisaoFormatada(Previsao previsao,
Estimativa estimativa)
String horaStr;
String minutoStr;
long horaAtual = Long.parseLong(previsao.getHorarioAtual());
long segundos = (estimativa.getHorarioPacote() - horaAtual) / 1000;
int semanas = (int) Math.floor(segundos / 604800);
segundos -= semanas * 604800;
int dias = (int) Math.floor(segundos / 86400);
segundos -= dias * 86400;
int horas = (int) Math.floor(segundos / 3600);
segundos -= horas * 3600;
int minutos = (int) Math.floor(segundos / 60);
segundos -= minutos * 60;
minutos += 1;
if (horas < 10)
horaStr = "0" + horas;
else
horaStr = String.valueOf(horas);
if (minutos < 10)
minutoStr = "0" + minutos;
else
minutoStr = String.valueOf(minutos);
String tempo;
if (horas > 0)
tempo = horaStr + "h " + minutoStr + "min";
else
tempo = minutoStr + "min";
SimpleDateFormat spf = new SimpleDateFormat("HH:mm:ss");
tempo = tempo + " às "
+ spf.format(estimativa.getHorarioEstimado());
return tempo;
private void setBackGroundColor(Estimativa estimativa, TextView txtView)
// Imagem a ser exibida
switch (estimativa.getStatus())
case 0:
txtView.setBackgroundColor(context.getResources().getColor(
R.color.previsaoVerde));
break;
case 1:
txtView.setBackgroundColor(context.getResources().getColor(
R.color.previsaoLaranja));
break;
case 2:
txtView.setBackgroundColor(context.getResources().getColor(
R.color.previsaoVermelha));
break;
default:
break;
private class ConsultaPrevisaoBackGround extends AsyncTask<String, Void, String>
@Override
protected String doInBackground(String... params)
try
PrevisaoUtil pUtil = new PrevisaoUtil(pontoId.trim(), idLinha.trim(),
context);
p = pUtil.getPrevisao();
catch (Exception e)
return "error";
return "Executed";
@Override
protected void onPostExecute(String result)
if(result.equals("error"))
holder.showError();
return;
if ((p.getErro() != null) && (p.getErro().trim().length() > 0))
holder.showMsg(p.getErro());
if ((p.getPonto() == null) || (p.getPonto().size() == 0))
holder.showMsg(context.getResources().getString(
R.string.msgSemPrevisao));
holder.fillPrevisao(p);
对不起,大帖子,但信息多比信息少
更新
问题解决了,我从适配器中删除了 AsynkTask 内部类并放入了活动中。
【问题讨论】:
【参考方案1】:如果您想刷新您的 ListView,请调用
notifyDataSetChanged()
在您的适配器上。
也可以看看ListView.invalidateViews()
也看看这个问题和答案:How to refresh Android listview?
【讨论】:
不适合我,谢谢【参考方案2】:覆盖 ConsultaPrevisaoBackGround
private class ConsultaPrevisaoBackGround extends AsyncTask<String, Void, String>
ViewHolder holder;
public ConsultaPrevisaoBackGround(ViewHolder holder)
this.holder = holder;
使用 Holder 刷新 UI
【讨论】:
抱歉,我不明白这将如何解决问题。【参考方案3】:抱歉这个比较容易理解
private class ConsultaPrevisaoBackGround extends AsyncTask<String, Void, String>
ViewHolder holder;
public ConsultaPrevisaoBackGround(ViewHolder holder)
this.holder = holder;
@Override
protected String doInBackground(String... params)
try
PrevisaoUtil pUtil = new PrevisaoUtil(pontoId.trim(), idLinha.trim(),
context);
p = pUtil.getPrevisao();
catch (Exception e)
return "error";
return "Executed";
【讨论】:
以上是关于如何动态刷新 ListView? [复制]的主要内容,如果未能解决你的问题,请参考以下文章