package dk.itu.smdp.group2.questionnaire.model; import dk.itu.smdp.group2.R; import dk.itu.smdp.group2.questionnaire.utilities.GRadioGroup; import android.view.Gravity; import android.view.View; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.RadioButton; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; /** * A Question where the respondent chooses answers for several rows with * a number of identical choices for them all. * * @author Emil * */ public class MatrixQuestion extends Question{ private int max; private String[] columns; private String[] rows; private CompoundButton[][] matrix; private int[] checked = null; // results private View root; /** * Initializes the MatrixQuestion with the given parameters. It is necessary * to add the rows and set the columns afterwards for complete and correct * behavior. * * @param question The question to answer. * @param desc The more detailed description to the question if necessary. * Null or empty string will be seen as no description. * @param mandatory True if the Question should be marked as mandatory for the * Questionnaire to be complete. * @param maxPerRow The maximum number of selections per row (inclusive). */ public MatrixQuestion(String question, String description, boolean mandatory, int maxPerRow){ super(question,description,mandatory); max = maxPerRow; } @Override public View generateView() { // inflate and fetch objects root = this.getParent().getActivity().getLayoutInflater().inflate(R.layout.question_matrix, null); TextView title = (TextView) root.findViewById(R.id.tvMatrixTitle); TextView desc = (TextView) root.findViewById(R.id.tvMatrixDesc); TextView select = (TextView) root.findViewById(R.id.tvMatrixSelec); TableLayout tablelayout = (TableLayout) root.findViewById(R.id.tlMatrix); // set values title.setText(this.getQuestionText()); desc.setText(this.getDescription()); if(getDescription() == null || getDescription().length() == 0) desc.setVisibility(View.GONE); // guide text if(max == 1){ // radio select.setVisibility(View.GONE); }else{ // checkbox select.setText("Select up to "+max+" options per line"); } // create grid titles createMatrix(tablelayout); return root; } private void createMatrix(TableLayout tablelayout) { tablelayout.setStretchAllColumns(true); TableRow.LayoutParams rowParams = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT); TableRow.LayoutParams params = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT,1f); TableRow.LayoutParams comp_params = new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT,1f); comp_params.gravity = Gravity.CENTER; TableRow row; matrix = new CompoundButton[rows.length][columns.length]; // first row = column names row = new TableRow(getParent().getActivity()); row.setLayoutParams(rowParams); TextView topleft = new TextView(getParent().getActivity()); topleft.setLayoutParams(params); row.addView(topleft); // empty topleft for(int i = 0; i < columns.length; i++){ // columns String s = columns[i]; TextView tv = new TextView(getParent().getActivity()); tv.setText(s); tv.setLayoutParams(params); row.addView(tv); } tablelayout.addView(row); checked = new int[rows.length]; // create rows for(int i = 0; i < rows.length; i++){ row = new TableRow(getParent().getActivity()); row.setLayoutParams(rowParams); String r = rows[i]; TextView tv = new TextView(getParent().getActivity()); tv.setText(r); tv.setLayoutParams(params); tv.setSingleLine(false); row.addView(tv); // create radio or checkbox if(max == 1){ GRadioGroup rg = new GRadioGroup(getParent()); for(int j = 0; j < columns.length; j++){ RadioButton rb = new RadioButton(getParent().getActivity()); rb.setLayoutParams(comp_params); matrix[i][j] = rb; row.addView(rb); rg.addRadioButton(rb); } }else{ final int ii = i; for(int j = 0; j < columns.length; j++){ CheckBox cb = new CheckBox(getParent().getActivity()); cb.setLayoutParams(comp_params); matrix[i][j] = cb; row.addView(cb); cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { checked[ii] += isChecked ? 1 : -1; // uncheck again if too many if(isChecked && checked[ii] > max){ buttonView.setChecked(false); checked[ii]--; }else{ // make questions visible/invisible if they have this as condition getParent().checkConditions(); } } }); } } tablelayout.addView(row); } } @Override public String toString(){ if (!isAnswered()) return ""; StringBuilder builder = new StringBuilder(); for(int x = 0; x < matrix.length; x++){ String s = ""; for(int y = 0; y < matrix[x].length; y++) if (((CompoundButton)matrix[x][y]).isChecked()) s += (s.length() == 0 ? "" : ", ") + columns[y]; builder.append(rows[x]+ ": " + s + "\n"); } builder.setLength(builder.length() - 1); return builder.toString(); } @Override public boolean isAnswered() { if(max == 1){ // radiobuttons for(View[] row : matrix){ boolean found = false; for(View v : row){ RadioButton rb = (RadioButton)v; if(rb.isChecked()) found = true; } if(!found) return false; } return true; }else{ // checkboxes for(int i : checked){ System.out.println(i); if(i == 0) return false; } return true; } } @Override public void setVisible(boolean visible) { root.setVisibility(visible ? View.VISIBLE : View.GONE); } /** * Sets the columns of possible choices (for each row) * to the names given. * * @param names Any number of Strings defining the * possible choices. */ public void setColumns(String... names) { this.columns = names; } /** * Sets the rows of questions to consider. * * @param rows Any number of Strings defining the * things to answer. */ public void setRows(String... rows) { this.rows = rows; } // PRIVATE HELPERS }