如何动态刷新ListView?

时间:2013-09-11 22:15:23

标签: java android android-listview android-asynctask

我正在尝试使用刷新值dinamic的ListAdapter。如果我不需要从互联网连接(我的情况)获取值,这不是一个大问题。

为此,我在我的适配器中实现了一个AsyncTask内部类,但是屏幕值的更新不起作用。执行所有过程时没有错误,但屏幕上的信息不会改变。

关于我的代码的一些评论如下:

我的方法getView被执行并调用ConsultaPrevisaoBackGround(我的AsyncTask)来查询来自互联网的值,他在getView方法的末尾执行。

在AsyncTask类中,我从互联网获取值,并在onPostExecuteMethod中调用方法来刷新我的持有者(类到封装小部件itens)。它工作正常(运行),但不反映在屏幕信息中。事实上,有时候有时不更新屏幕。

我的怀疑是:

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内部类并放入了活动。

3 个答案:

答案 0 :(得分:0)

如果您想刷新您的ListView,请致电

 notifyDataSetChanged()
适配器上的

另请查看ListView.invalidateViews()

另请查看此问题和答案: How to refresh Android listview?

答案 1 :(得分:0)

覆盖 ConsultaPrevisaoBackGround

private class ConsultaPrevisaoBackGround extends AsyncTask<String, Void, String> {
    ViewHolder holder;
    public  ConsultaPrevisaoBackGround(ViewHolder holder){
        this.holder = holder;
    }

使用Holder刷新UI

答案 2 :(得分:0)

抱歉,这更容易理解

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";
}

}