Salivan
Salivan

Reputation: 1903

ListView first item has wrong values

I have a ListView which is filled by CursorAdapter. Each item of this ListView has 5 child Views. I set values of these child Views in my CursorAdapter's onBind() (I'm using ViewHolder pattern). The values are these: phone number, call state, comments count, call duration, time when the call happened. If call was missed or dropped, I set the duration View to be INVISIBLE. Everything is fine while all the calls are "answered", but, if there appears a call that is missed or dropped then the first item in the ListView, I repeat ALWAYS AND ONLY THE FIRST ITEM, has the duration View set to be INVISIBLE and count View with wrong value. I don't get it. All the other first items Views are set correctly, but the duration is for some reason wrong. Please help me to figure this out.

This is my CursorAdaper code:

package com.example.nrsearch.adapter;

import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.nrsearch.R;
import com.example.nrsearch.Utils;

public class NumberListAdapter extends CursorAdapter {
private static final String KEY_NUMBER = "number";
private static final String KEY_STATE = "state";
private static final String KEY_COUNT = "count";
private static final String KEY_TIME = "time";
private static final String KEY_DURATION = "duration";

public NumberListAdapter(Context context, Cursor c, int flags) {
    super(context, c, flags);
}

private class ViewHolder {
    private TextView numberView;
    private ImageView stateView;
    private TextView countView;
    private TextView timeView;
    private TextView durationView;
}

@Override
public View newView(Context context, Cursor c, ViewGroup parent) {
    Log.i(Utils.TAG, "newView() is called");
    View view = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
            .inflate(R.layout.numberlistitem, parent, false);

    ViewHolder holder = new ViewHolder();
    holder.numberView = (TextView) view.findViewById(R.id.number);
    holder.stateView = (ImageView) view.findViewById(R.id.state);
    holder.countView = (TextView) view.findViewById(R.id.count);
    holder.timeView = (TextView) view.findViewById(R.id.time);
    holder.durationView = (TextView) view.findViewById(R.id.duration);

    view.setTag(holder);

    return view;
}

@Override
public void bindView(View view, Context context, Cursor c) {
    Log.i(Utils.TAG, "bindView() is called");

    ViewHolder holder = (ViewHolder) view.getTag();

    holder.numberView.setText(c.getString(c.getColumnIndexOrThrow(KEY_NUMBER)));
    int stateCode = c.getInt(c.getColumnIndexOrThrow(KEY_STATE));
    if (stateCode == 0) holder.stateView.setBackgroundResource(R.drawable.red_arrow);
    else holder.stateView.setBackgroundResource(R.drawable.green_arrow);

    int count = c.getInt(c.getColumnIndexOrThrow(KEY_COUNT));
    if (count == -2) holder.countView.setBackgroundResource(R.drawable.count_bubble_unknown);
    else if (count == -1) holder.countView.setBackgroundResource(R.drawable.count_bubble_blocked);
    else {
        holder.countView.setBackgroundResource(R.drawable.count_bubble);
        holder.countView.setText(""+count);
    }

    holder.timeView.setText(parseElapsedTime(c.getLong(c.getColumnIndexOrThrow(KEY_TIME)),
            System.currentTimeMillis() / 1000L));


    if (stateCode != 0) {
        long duration = c.getLong(c.getColumnIndexOrThrow(KEY_DURATION));
        holder.durationView.setText(parseDuration(duration));
    } else holder.durationView.setVisibility(View.INVISIBLE);
}

private String parseElapsedTime(long pastTimeSecs, long presentTimeSecs) {
    long elapsedTimeSecs = presentTimeSecs - pastTimeSecs;
    if (elapsedTimeSecs >= 60L && elapsedTimeSecs < 3600L) {
        return "Pries " + Math.round(elapsedTimeSecs / 60L) + " min.";
    } else if (elapsedTimeSecs >= 3600L && elapsedTimeSecs < 86400L) {
        return "Pries " + Math.round(elapsedTimeSecs / 3600L) + " val.";
    } else if (elapsedTimeSecs >= 86400L && elapsedTimeSecs < 604800L) {
        return "Pries " + Math.round(elapsedTimeSecs / 86400L) + " d.";
    } else if (elapsedTimeSecs >= 604800L && elapsedTimeSecs < 2592000L) {
        return "Pries " + Math.round(elapsedTimeSecs / 604800L) + " sav.";
    } else if (elapsedTimeSecs >= 2592000L && elapsedTimeSecs < 31536000L) {
        return "Pries " + Math.round(elapsedTimeSecs / 2592000L) + " men.";
    } else if (elapsedTimeSecs >= 31536000L) {
        return "Pries " + Math.round(elapsedTimeSecs / 31536000L) + " m.";
    } else return "Pries " + Long.toString(elapsedTimeSecs) + " s.";
}

private String parseDuration(long timeSeconds) {
    int hours = Math.round(timeSeconds / 3600);
    int minutes = Math.round((timeSeconds - hours * 3600) / 60);
    long seconds = timeSeconds - hours * 3600 - minutes * 60;

    String h, min, s;

    if (hours / 10 < 1)
        h = "0" + hours;
    else
        h = "" + hours;
    if (minutes / 10 < 1)
        min = "0" + minutes;
    else
        min = "" + minutes;
    if (seconds / 10 < 1)
        s = "0" + seconds;
    else
        s = "" + seconds;

    return h + ":" + min + ":" + s;
}

}

Upvotes: 0

Views: 335

Answers (1)

Lev
Lev

Reputation: 443

    if (stateCode != 0) {
       long duration = c.getLong(c.getColumnIndexOrThrow(KEY_DURATION));
       holder.durationView.setText(parseDuration(duration));
       holder.durationView.setVisibility(View.VISIBLE)
    } else{
       holder.durationView.setVisibility(View.INVISIBLE);
    }

Try setting the visibility to VISIBLE in the if clause. I had a problem with this recently.

Upvotes: 1

Related Questions