Por lo que he leído en StackOverflow, debe ser eso que mencionas. Por ahí deben de ir los tiros.
Creo que tiene que ver con que en el instantiateItem me debe estar sobreescribiendo la View por otra distinta. La prueba es que meto un punto de interrupción en el getCount del adaptador del listview y está devolviendo el número de filas que tiene otro listview de otra vista y no la que está en pantalla.
Y claro, el casque pasa justamente cuando pincho en una fila del listview segundo que carga.
Se ve que las vistas y sus adaptadores no están relacionadas por algo que estoy haciendo mal.
Para ir más al grano, el chocho debe de estar en la función UpdateView. Esa función la llamo tanto en el instantiateItem como en el onPostExecute del AsyncTask. La diferencia está en comprobar si el arraylist es nulo (entonces ejecuto el AsyncTask para cargar el arraylist con los datos) o tiene algo (entonces instancio el adaptador del listview). Es en el punto en el que instancio el adaptador del listview donde algo estoy haciendo mal. Quizás no sea ahí donde tenga que cargar el listview, no sé...
Este el OnCreate de la Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lay_act_executions);
Bundle bundle = getIntent().getExtras();
piIdProcess = bundle.getString("p_id");
setTitle("Ejecuciones");
miAdapter = new ColumnasAdapter(this,piIdProcess);
columnas = (ViewPager) findViewById(R.id.columnas);
columnas.setAdapter(miAdapter);
TitlePageIndicator titleIndicator = (TitlePageIndicator)findViewById(R.id.titulos);
titleIndicator.setViewPager(columnas);
titleIndicator.setFooterIndicatorStyle(IndicatorStyle.Triangle);
titleIndicator.setCurrentItem(miAdapter.getCount()-1);
titleIndicator.setOnPageChangeListener(this);
}
Aunque no es relevante, también adjunto la clase donde cargo la estructura de datos que se pintan en cada fila:
public class cExecution implements Parcelable {
private String mStrSerie = "";
private String mStrOut = "";
private String mStrHora = "";
private String mStrTiempo = "";
private String mStrLevel = "";
public void setSerie(String pStrCode) {
this.mStrSerie = pStrCode;
}
public void setOut(String pStrOut) {
this.mStrOut = pStrOut;
}
public void setHora(String pStrHora) {
this.mStrHora = pStrHora;
}
public void setTiempo(String pStrTiempo) {
this.mStrTiempo = pStrTiempo;
}
public void setLevel(String pStrLevel) {
this.mStrLevel = pStrLevel;
}
public String getSerie() {
return this.mStrSerie;
}
public String getOut() {
return this.mStrOut;
}
public String getHora() {
return this.mStrHora;
}
public String getTiempo() {
return this.mStrTiempo;
}
public String getLevel() {
return this.mStrLevel;
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
}
}
Este es el adaptador del listview:
public class cAdaptadorExecutions extends BaseAdapter {
private static ArrayList<cExecution> alExecutions;
private LayoutInflater mInflater;
public cAdaptadorExecutions(Context context,ArrayList<cExecution> palExecutions) {
alExecutions = palExecutions;
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return alExecutions.size();
}
public Object getItem(int position) {
return alExecutions.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.layout_fila_exec, null);
holder = new ViewHolder(convertView, alExecutions.get(position).getLevel());
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//holder.tvSerie.setText(alExecutions.get(position).getSerie());
holder.tvOut.setText(alExecutions.get(position).getOut());
holder.tvHora.setText(alExecutions.get(position).getHora());
holder.tvTiempo.setText("Segundos: "+alExecutions.get(position).getTiempo());
//holder.tvLevel.setText(alExecutions.get(position).getLevel());
return convertView;
}
private class ViewHolder {
TextView tvLevel;
TextView tvSerie;
TextView tvOut;
TextView tvHora;
TextView tvTiempo;
ImageView imvIcono;
public ViewHolder(View fila, String level) {
//tvCode = (TextView) fila.findViewById(R.id.txtCode);
tvOut = (TextView) fila.findViewById(R.id.txtOut);
tvHora = (TextView) fila.findViewById(R.id.txtHora);
tvTiempo = (TextView) fila.findViewById(R.id.txtTiempo);
imvIcono = (ImageView) fila.findViewById(R.id.imvIcono);
if (level.equals("0")) {
imvIcono.setImageResource(R.drawable.unknown);
} else if (level.equals("1")) {
imvIcono.setImageResource(R.drawable.ok);
} else if (level.equals("2")) {
imvIcono.setImageResource(R.drawable.exclamation);
} else if (level.equals("3")) {
imvIcono.setImageResource(R.drawable.cancel);
} else {
imvIcono.setImageResource(R.drawable.unknown);
}
}
}
}
Y ahora viene la madre del cordero donde debe de estar cagándola. El adaptador del ViewPager. Es algo complejo porque al tener que consultar una base de datos, uso un AsyncTask. Sí... sé que lo suyo es leer el xml que me devuelva un script en .php, por ejemplo. Pero como es un pequeño proyecto interno estoy tirando directamente la query, no es echéis encima mío xDDD. Y no hace falta empollarse la creación de las páginas. Pillé el ejemplo de aquí:
https://bitbucket.org/ayastrebov/android-infinite-viewpager/src/b69ee64cfbe4/ViewPager-Sample/src/com/stonerhawk/viewpager/MyPagerAdapter.java
public class ColumnasAdapter extends PagerAdapter implements TitleProvider {
private static final DateFormat dfTitle = new SimpleDateFormat("E, dd MMM");
private static final int daysSize = 7;
private static Date[] dates = new Date[ daysSize ];
private LayoutInflater mInflater = null;
private Context ctx;
ProgressDialog dialog;
public String mIdProcess;
ListView lvExecutions;
private cAdaptadorExecutions ExecutionAdapter;
public ColumnasAdapter(Context context, String piIdProcess)
{
ctx = context;
mIdProcess = piIdProcess;
dialog = null;
dialog = new ProgressDialog(ctx);
prepareDates();
this.mInflater = LayoutInflater.from(ctx);
}
private void prepareDates()
{
Date today = new Date();
Calendar calFecha = Calendar.getInstance();
// Situamos la variable fecha en el día de hoy
calFecha.setTime(today);
// Le restamos los días del rango
calFecha.add( Calendar.DATE, daysSize*(-1));
// Llenamos el array con los días siguientes al inicio del rango hasta hoy
for (int i = 0; i < daysSize; i++)
{
calFecha.add( Calendar.DATE, 1 );
dates[ i ] = calFecha.getTime();
}
}
@Override
public int getCount() {
return dates.length;
}
@Override
public Object instantiateItem(View collection, int position) {
if (this.dialog == null ) {
this.dialog = new ProgressDialog(this.ctx);
}
View v = drawView(position, ( (ViewPager) collection).getChildAt(position));
((ViewPager) collection).addView(v);
return v;
}
private View drawView(int position, View view)
{
view = mInflater.inflate(R.layout.lay_act_vp_executions, null);
updateView(position, view, null);
return view;
}
private void updateView(int position, View view, ArrayList<cExecution> palExecutions)
{
lvExecutions = (ListView) view.findViewById(R.id.lsvExecutions);
if (palExecutions != null) {
ExecutionAdapter = new cAdaptadorExecutions(this.ctx,palExecutions);
lvExecutions.setAdapter(ExecutionAdapter);
if (this.dialog.isShowing()) this.dialog.dismiss();
} else {
DateFormat dfQuery = new SimpleDateFormat("yyyy-MM-dd");
new LoadContentTask().execute(position, view, dfQuery.format( dates[position] ), this.mIdProcess);
if (! this.dialog.isShowing()) {
this.dialog.setMessage("Cargando...");
this.dialog.setIndeterminate(false);
this.dialog.show();
}
}
}
private class LoadContentTask extends AsyncTask<Object, Object, Object>
{
private Integer position;
private View view;
@Override
protected void onPreExecute() {
}
@Override
protected Object doInBackground(Object... arg)
{
position = (Integer) arg[0];
view = (View) arg[1];
ArrayList<cExecution> alExecutions = new ArrayList<cExecution>();
try
{
java.sql.Connection conn;
String cadenaFecha = (String) arg[2];
alExecutions.clear();
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://xxx.yyy.z.pp:kkkk/xxxxx","xxxxx","xDDDDD");
Statement st = (Statement) conn.createStatement();
ResultSet rsExecutions = st.executeQuery("vease una select que está bien xD");
cExecution Execution = new cExecution();
while (rsExecutions.next())
{
Execution = new cExecution();
Execution.setSerie(rsExecutions.getString(1));
Execution.setOut(rsExecutions.getString(2));
Execution.setHora(rsExecutions.getString(3));
Execution.setTiempo(rsExecutions.getString(4));
Execution.setLevel(rsExecutions.getString(5));
alExecutions.add(Execution);
}
st.close();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
catch (SQLException e)
{
e.printStackTrace();
}
return alExecutions;
}
protected void onPostExecute(Object result)
{
updateView(position,view,(ArrayList<cExecution>) result);
view.postInvalidate();
//notifyDataSetChanged();
}
}
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager) collection).removeView((LinearLayout) view);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == ((LinearLayout) object);
}
@Override
public void finishUpdate(View arg0) {
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void startUpdate(View arg0) {
}
@Override
public String getTitle(int position) {
return dfTitle.format( dates[position] );
}
}
Por los foros la gente apela al notifySetDataChanged pero no ayuda en nada hacer eso. Los hilos de stackoverflow que más se acercan son estos:
http://stackoverflow.com/questions/3874506/android-listview-problem-when-refreshing
http://stackoverflow.com/questions/9714633/viewpager-listview-and-asynctask-first-page-blank-all-data-in-the-second-pag
Aquí hay un ejemplo de un pavo donde hace algo muy parecido a lo mío pero más sencillo al no tener que usar un hilo para cargar el listview:
http://blog.stylingandroid.com/archives/542
Cualquier ayuda sería de agradecer. Estoy desesperado y cuando me obsesiono, ni puedo dormir ni ná!