-1

My listview isn't updating correctly when I try to remove or copy an item. The data is storing correctly in the database, but is not displayed correctly on the listview, which I think is due to issues with recycling views.

For example, I deleted an item with id 87, then I copied a different item and it showed up in the listview as having an id of 87 even though it should have been 88 (and was correctly stored in the db as 88).

I've tried looking at some other examples of code with view holders and custom adapters, but I can't seem to figure out the issue. Have I applied the ViewHolder concept correctly to my custom adapter?

public class WorkoutAdapter extends ArrayAdapter<ExerciseSetModel> {

    private Context context;
    private ArrayList<ExerciseSetModel> exerciseSetList;
    private JSONParser jParser = new JSONParser();
    private String isComplete;
    private String exerciseId;

    public WorkoutAdapter(Context context, ArrayList<ExerciseSetModel> objects) {

        super(context, R.layout.exercise_set_item, objects);

        this.context = context;
        this.exerciseSetList = objects;
        isComplete = "";
    }

    private class ViewHolder{
        TextView tvExerciseSetName;
        TextView tvExerciseSetDetails;
        CheckBox cbIsComplete;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        RelativeLayout view = (RelativeLayout) convertView;
        ViewHolder holder = null;

        if (view == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = (RelativeLayout) inflater.inflate(R.layout.exercise_set_item, parent, false);

            holder = new ViewHolder();
            holder.tvExerciseSetName = (TextView) view.findViewById(R.id.exerciseSetName);
            holder.tvExerciseSetDetails = (TextView) view.findViewById(R.id.exerciseSetDetails);
            holder.cbIsComplete = (CheckBox) view.findViewById(R.id.cbIsComplete);

            if (exerciseSetList.get(position).getIsComplete() == 1) {
                holder.cbIsComplete.setChecked(true);
                isComplete = "1";
            }
            else {
                holder.cbIsComplete.setChecked(false);
                isComplete = "0";
            }

            holder.cbIsComplete.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (isChecked) {
                        exerciseSetList.get(position).setIsComplete(1);
                        exerciseId = exerciseSetList.get(position).getExerciseId() + "";
                        isComplete = "1";
                    } else {
                        exerciseSetList.get(position).setIsComplete(0);
                        exerciseId = exerciseSetList.get(position).getExerciseId() + "";
                        isComplete = "0";
                    }
                    new UpdateExerciseComplete().execute();
                }
            });

            holder.tvExerciseSetName.setText(exerciseSetList.get(position).getExerciseName());
            holder.tvExerciseSetDetails.setText(exerciseSetList.get(position).getExerciseDetails() + " id: " + exerciseSetList.get(position).getExerciseId());

        }
        else{
            holder = (ViewHolder) view.getTag();
        }

        return view;
    }

    class UpdateExerciseComplete extends AsyncTask<String, String, String> {

        private String updateIsCompleteUrl;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        protected String doInBackground(String... args) {

            updateIsCompleteUrl = "localhost/android_connect/updateIsComplete.php";

            LinkedHashMap<String, String> params = new LinkedHashMap<String, String>();
            params.put("is_complete", isComplete);
            params.put("exercise_id", exerciseId);
            jParser.makePostRequest(updateIsCompleteUrl, params);

            return null;
        }

        protected void onPostExecute(String file_url) {
        }
    }
}
wahnaton
  • 3
  • 3

2 Answers2

0

For getting correct position in onclick() function. you have to tag position on your view holder.cbIsComplete.setTag(position) then get this tag inside onCLick() using int position=(Integer)buttonView.getTag()

Jaiprakash Soni
  • 4,100
  • 5
  • 36
  • 67
  • Not sure what you are talking about. The check box is working fine and is unrelated to my question. – wahnaton Oct 28 '15 at 04:30
0

You have implemented wrong ViewHolder pattern. replace modified getView

 @Override
public View getView(final int position, View convertView, ViewGroup parent) {

    RelativeLayout view = (RelativeLayout) convertView;
    ViewHolder holder = null;

    if (view == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = (RelativeLayout) inflater.inflate(R.layout.exercise_set_item, parent, false);

        holder = new ViewHolder();
        holder.tvExerciseSetName = (TextView) view.findViewById(R.id.exerciseSetName);
        holder.tvExerciseSetDetails = (TextView) view.findViewById(R.id.exerciseSetDetails);
        holder.cbIsComplete = (CheckBox) view.findViewById(R.id.cbIsComplete);
        view.setTag(holder); 
    }else{
        holder = (ViewHolder) view.getTag();
    }

    if (exerciseSetList.get(position).getIsComplete() == 1) {
        holder.cbIsComplete.setChecked(true);
        isComplete = "1";
    }
    else {
        holder.cbIsComplete.setChecked(false);
        isComplete = "0";
    }

    holder.cbIsComplete.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                exerciseSetList.get(position).setIsComplete(1);
                exerciseId = exerciseSetList.get(position).getExerciseId() + "";
                isComplete = "1";
            } else {
                exerciseSetList.get(position).setIsComplete(0);
                exerciseId = exerciseSetList.get(position).getExerciseId() + "";
                isComplete = "0";
            }
            new UpdateExerciseComplete().execute();
        }
    });

    holder.tvExerciseSetName.setText(exerciseSetList.get(position).getExerciseName());
    holder.tvExerciseSetDetails.setText(exerciseSetList.get(position).getExerciseDetails() + " id: " + exerciseSetList.get(position).getExerciseId());

    return view;
}
Kishore Jethava
  • 6,666
  • 5
  • 35
  • 51
  • This doesn't work. I get a NullPointerExeception at this spot: if (exerciseSetList.get(position).getIsComplete() == 1) { holder.cbIsComplete.setChecked(true); isComplete = "1"; } else { holder.cbIsComplete.setChecked(false); isComplete = "0"; } – wahnaton Oct 28 '15 at 04:32
  • sorry i have forgot to add `view.setTag(holder);` see edited answer.! – Kishore Jethava Oct 28 '15 at 05:43