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.