0

I'm back with a question. First, please take a look at this image here: Image 1: Click here What I am trying to do here is make the CheckBox (cb_exercisedone) get checked automatically when the user checks all the ones in the sets (cb_setdone).
A simple idea but maybe my list Adapter is what made it almost impossible for me, because I tried to make it work for hours and of course read a dozen similar questions here on SO.
Lets cut to the chase, here is my code:
ExerciseAdapter.java

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.TextView;

import com.example.workoutapp.R;
import com.rabiiapps.model.Exercise;

public class ExerciseAdapter extends ArrayAdapter<Exercise> {
    private ArrayList<Exercise> exercises;
    private LayoutInflater inflater;

    // list with title positions in listview
    public static List<Integer> HEADER_VIEW_LIST = new ArrayList<Integer>(); 

    public ExerciseAdapter(Context context, int textViewResourceId, ArrayList<Exercise> objects) {
        super(context, textViewResourceId, objects);
        exercises = objects;
        inflater = (LayoutInflater) getContext().
                getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getItemViewType(int position) {
        for(int i=0; i<HEADER_VIEW_LIST.size(); i++) {
            if (position == HEADER_VIEW_LIST.get(i)) return 0;
        }
        return 1;
    }

    @Override
    public int getViewTypeCount() {
        return 2; // two types of rows, exercise headers and bodies (sets)
    }

    public View getView(final int position, View convertView, ViewGroup parent){
        View view = convertView;
        Holder holder = null;

        if (getItemViewType(position) == 0) {

            if (view == null) {

                view = inflater.inflate(R.layout.item_exercise_header, null);
                holder = new Holder();
                holder.exerciceTitleView = (TextView) view.findViewById(R.id.tv_exercice_title);
                view.setTag(holder);

            } else {

                holder = (Holder) convertView.getTag();
            }

            Exercise exercise = exercises.get(position);
            if (exercise != null)
                holder.exerciceTitleView.setText(exercise.getTitle());

            holder.cbExercise = (CheckBox) view.findViewById(R.id.cb_exercisedone);

        } else {

            if (view == null) {

                view = inflater.inflate(R.layout.item_set, null);
                holder = new Holder();
                holder.setCounterView = (TextView) view.findViewById(R.id.tv_set_counter);  
                view.setTag(holder);

            } else {

                holder = (Holder) convertView.getTag();

            }

            Exercise exercice = exercises.get(position);
            if (exercice != null)
                holder.setCounterView.setText(String.valueOf(exercice.getSetCount()));

        }       

        return view;
    }

    static class Holder {
        // header row items
        CheckBox cbExercise;
        TextView exerciceTitleView;

        // body row item
        CheckBox cbSet;
        TextView setCounterView;
    }

}

MediumActivity.java same as ProfessionalActivity which is in the image 1.

import java.util.ArrayList;

import com.example.workoutapp.R;
import com.rabiiapps.helper.ExerciseAdapter;
import com.rabiiapps.model.Exercise;

import android.app.ListActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;

public class MediumActivity extends ListActivity {

    private ArrayList<Exercise> mExercise = new ArrayList<Exercise>();
    private Runnable viewParts;
    private ExerciseAdapter adapter;
    private TextView infoTextView;
    private TextView programNameView;
    private int positionCounter = 0;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_program);

        // header
        infoTextView = (TextView) findViewById(R.id.tv_program_info);
        programNameView = (TextView) findViewById(R.id.tv_program_name);

        programNameView.setText("Medium Program");
        infoTextView.setText("Medium info goes here...");
        /*
         * back to our list
         */

        // adapter
        adapter = new ExerciseAdapter(this, R.layout.item_set, mExercise);
        setListAdapter(adapter);

        // here we are defining our runnable thread.
        viewParts = new Runnable(){
            public void run(){
                handler.sendEmptyMessage(0);
            }
        };

        Thread thread =  new Thread(null, viewParts, "WorkoutThread");
        thread.start();

        ExerciseAdapter.HEADER_VIEW_LIST.clear(); // lose title positions when done
    }
    private Handler handler = new Handler()
     {
        public void handleMessage(Message msg)
        {
            // Sets + reps etc for medium
            addExercice("Medium training 1", 2);
            addExercice("Medium training 2", 4);
            addExercice("Medium training 3", 3);

            adapter = new ExerciseAdapter(MediumActivity.this, R.layout.item_set, mExercise);
            setListAdapter(adapter);
        }
    };

    public void addExercice(String title, int sets) {
        mExercise.add(new Exercise(title));
        ExerciseAdapter.HEADER_VIEW_LIST.add(positionCounter);
        positionCounter++;
        for(int i=1; i<sets+1; i++) {
            mExercise.add(new Exercise(i));
            positionCounter++;
        }
    }
}

I'm not sure if you will need this but here is the layouts aswell: activity_program.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv_program_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Program name"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/tv_program_info"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:layout_weight="0.20"
        android:text="program info, talk abt sets, reps, weight etc..." />

    <ListView
        android:id="@+id/android:list"
        android:layout_width="match_parent"
        android:layout_height="395dp" >
    </ListView>

    <Button
        android:id="@+id/bt_savework"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.03"
        android:text="Save Workout" />

</LinearLayout>

item_exercise_header.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp" >
    <TextView
        android:id="@+id/tv_exercice_title"
        android:layout_width="270dp"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/cb_exercisedone"
        android:layout_alignParentTop="true"
        android:gravity="center_vertical"
        android:text="Exercice title"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <CheckBox
        android:id="@+id/cb_exercisedone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:enabled="false" />

</RelativeLayout>

item_set.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp" >

    <LinearLayout
        android:id="@+id/ll_set"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:orientation="horizontal" >

        <CheckBox
            android:id="@+id/cb_setdone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/tv_set"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="7dp"
            android:text="Set" />

        <TextView
            android:id="@+id/tv_set_counter"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="3dp"
            android:text="1" />

        <TextView
            android:id="@+id/tv_reps"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="15dp"
            android:text="Reps x" />

        <EditText
            android:id="@+id/et_reps_number"
            android:layout_width="47dp"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="number" />

        <TextView
            android:id="@+id/tv_weight"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="15dp"
            android:text="Weight" />

        <EditText
            android:id="@+id/et_weight_number"
            android:layout_width="65dp"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="number" />

        <TextView
            android:id="@+id/tv_weight_unit"
            android:layout_width="59dp"
            android:layout_height="wrap_content"
            android:text="kg/lbs"
            android:textAppearance="?android:attr/textAppearanceSmall" />
    </LinearLayout>


</RelativeLayout>

Please help me with your ideas, for the problem of the checkbox mainly but if you see there could be any enhancement in the way I handled the listView or anything else feel free to let me know in your answer. Thank you for reading.

Edit: I solved it, I used the positions in the listview and the number of sets.

siriuseteor77
  • 1,004
  • 2
  • 12
  • 30
  • [try this Listview + checkbox](http://stackoverflow.com/questions/25013227/listview-checkbox/25013826#25013826) – Kaushik Sep 15 '14 at 06:07
  • Thanks kaushik, I saw that question and I tried that in different means but no luck. – siriuseteor77 Sep 15 '14 at 16:46
  • follow this [tutorial](http://www.vogella.com/tutorials/AndroidListView/article.html) this will help you – Kaushik Sep 16 '14 at 04:53
  • Thanks kaushik but I think I lack experience to get it to work. Instead if I wanted to use this: [views in listview](http://stackoverflow.com/questions/11652814/android-listview-in-listview) can you help me do that please? – siriuseteor77 Sep 17 '14 at 18:42

2 Answers2

0

first you need to get the count of all the item in the list view. Listview.getCount(); where the listview is the array used to populate the Adapter. Now let us say the number of item is 20. each time you check a checkbox, decrement the count by one, once the count is 0, then you can set the final checkboxe checked.

random example

int count = list.getCount();

In the adapter

check_box.setOnclickListener(new OnClickListener(){
    @Override
    public void onClick(View v){
         if(check_box.isChecked(){
         count--;
         }else{
         //if you uncheck the box, then increment the count
         count++;
         }
         //now check if all check_boxes are checked
         if(count==0)
          // code to check the last checkBox because all are checked
         else
           //code to uncheck the last checkbox if it was checked and you just unchecked a boxe
    }
});

It should be something like this : in your activity, create the variable count

int count = mExercise.size();//this will give you the amount of checkboxes

then in your adapter :

public View getView(final int position, View convertView, ViewGroup parent){
    View view = convertView;
    Holder holder = null;

    if (getItemViewType(position) == 0) {

        if (view == null) {

            view = inflater.inflate(R.layout.item_exercise_header, null);
            holder = new Holder();
            holder.exerciceTitleView = (TextView) view.findViewById(R.id.tv_exercice_title);
            view.setTag(holder);

        } else {

            holder = (Holder) convertView.getTag();
        }

        Exercise exercise = exercises.get(position);
        if (exercise != null)
            holder.exerciceTitleView.setText(exercise.getTitle());

        holder.cbExercise = (CheckBox) view.findViewById(R.id.cb_exercisedone);

    } else {

        if (view == null) {

            view = inflater.inflate(R.layout.item_set, null);
            holder = new Holder();
            holder.setCounterView = (TextView) view.findViewById(R.id.tv_set_counter);  
            view.setTag(holder);

        } else {

            holder = (Holder) convertView.getTag();

        }
        holder.cbExercise.setOnClickListener(new OnClickListener()){
           @Override
           public void onClick(View v){
               if(holder.cbExercise.isChecked())
                   count--;
                else
                   count++;
                //now the final checkbox
                if(count==0)
                    final_check_boxe.setChecked(true);
                else
                    final_check_boxe.setChecked(false);
           }
        }
        Exercise exercice = exercises.get(position);
        if (exercice != null)
            holder.setCounterView.setText(String.valueOf(exercice.getSetCount()));

    }       

    return view;
}

I haven't try it but it should definitelly work

Jayo2k
  • 251
  • 3
  • 14
  • I tried almost the same thing but I was very confused trying to grab the checkboxes, as the views are not the same so could you please go into details a little more? Thank you. – siriuseteor77 Sep 15 '14 at 01:18
  • I actually want the check-boxes cb_exercise (the one on the top) to be checked when all the cb_setdone check-boxes are checked (all the ones underneath it). Either way, I tried this in different ways again and got different results. But for this exact try I get a NullPointerException on "cb_exercisedone.setChecked(true);" It also refused the onClickListener but instead I tried onCheckedChangeListener.. – siriuseteor77 Sep 15 '14 at 19:17
  • I finish my current code and when I am done, I will work on that one – Jayo2k Sep 15 '14 at 19:35
  • sure, take your time. – siriuseteor77 Sep 15 '14 at 19:39
  • Any help would be appreciated Jayo2k, I'm on a dead end here. – siriuseteor77 Sep 17 '14 at 18:43
  • oh yes, I haven't forgot, right now the code I am working on is giving me headache, but I promess i will work on your code this evening – Jayo2k Sep 17 '14 at 19:15
0

I fixed this after days of research and trying and this is the fix for everyone who stumbled upon the same problem:

holder.cbSet.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton button, boolean isChecked) {

        if(isChecked)
            mExercise.get(position).setCbChecked(true);
        else
            mExercise.get(position).setCbChecked(false);
    }
});

holder.cbSet.setChecked(exercise.isCbChecked());
siriuseteor77
  • 1,004
  • 2
  • 12
  • 30