I'm trying implement ListAdapter that refresh values dinamic. It's not a big problem if I did not need get values from internet connection (my case).
To do this, I have implemented a AsyncTask inner class in my adapter, but the update of screen values not work. All process is executed with no errors, but the informations on screen not change.
Some comments about my code bellow:
My method getView is executed and call ConsultaPrevisaoBackGround (my AsyncTask) to consult values from internet, he is executed in the end of getView method.
In the AsyncTask class i get values from internet and, in the onPostExecuteMethod, call methods to refresh my holder (class to encapsule widgets itens). It's work fine (running), but not reflect in screen informations. In fact, sometimes update the screen sometimes not.
My doubts are:
1 - My strategy is correct? If yes, where is the error? 2 - What I can do to execute this process once, to not execute each time that the user roller the screen?
I'm working on this for a long time and can not find solution... help!!
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);
}
}
}
Sorry by the big post, but much information is better than little information
UPDATE
The problem is solved, I remove the AsynkTask innerclass from adapter and put in activity.