Skip to content

Instantly share code, notes, and snippets.

@rogamaral
Created March 24, 2018 21:51
Show Gist options
  • Save rogamaral/2c0bc5b365179afeaa304e99cc595713 to your computer and use it in GitHub Desktop.
Save rogamaral/2c0bc5b365179afeaa304e99cc595713 to your computer and use it in GitHub Desktop.
Implementação de uma lista de perguntas com resposta multi-escolha. usando ExpandableListView
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin">
<TextView
android:id="@+id/textView"
android:text="Questionário"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="32dp"/>
<ExpandableListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/expandableListView"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
//Responsável por guardar o texto da resposta.
public class Answer {
private final String answerText;
public Answer(String text){
this.answerText = text;
}
public String getText() {
return answerText;
}
}
<!--View para as respostas, representa cada um dos sub-itens dentro de cada grupo da ExpandableListView.-->
<!--Contém um RadioButton com o texto da resposta.-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New RadioButton"
android:id="@+id/answerText"
android:clickable="false"
android:focusable="false"/>
</LinearLayout>
//Responsável por fazer a ponte entre os dados e a ExpandableListView
public class ExpandListAdapter extends BaseExpandableListAdapter {
private final LayoutInflater inflater;;
private ArrayList<Question> questions;
public ExpandListAdapter(Context context, ArrayList<Question> questions){
inflater = LayoutInflater.from(context);
this.questions = questions;
}
@Override
public int getGroupCount() {
return questions.size();
}
@Override
public int getChildrenCount(int groupPosition) {
ArrayList<Answer> answers = questions.get(groupPosition).getAnswers();
if(answers == null){
return 0;
}
return questions.get(groupPosition).getAnswers().size();
}
@Override
public Object getGroup(int groupPosition) {
return questions.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return questions.get(groupPosition).getAnswers().get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder;
if (row == null)
{
row = inflater.inflate(R.layout.question_row, parent, false);
holder = new ViewHolder();
holder.addView(row.findViewById(R.id.questionText))
.addView(row.findViewById(R.id.correctMark));
row.setTag(holder);
}else{
holder = (ViewHolder) row.getTag();
}
TextView questionText = (TextView) holder.getView(R.id.questionText);
CheckBox correctMark = (CheckBox) holder.getView(R.id.correctMark);
Question question = questions.get(groupPosition);
if(question.isCorrectlyAnswered()) {
correctMark.setVisibility(View.VISIBLE);
}else {
correctMark.setVisibility(View.GONE);
}
questionText.setText(question.getText());
return row;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder;
if (row == null)
{
row = inflater.inflate(R.layout.answer_row, parent, false);
holder = new ViewHolder();
holder.addView(row.findViewById(R.id.answerText));
row.setTag(holder);
}else{
holder = (ViewHolder) row.getTag();
}
RadioButton answerText = (RadioButton) holder.getView(R.id.answerText);
if(questions.get(groupPosition).getSelectedAnswer() == childPosition){
answerText.setChecked(true);
}else{
answerText.setChecked(false);
}
answerText.setText(questions.get(groupPosition).getAnswers().get(childPosition).getText());
return row;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
static class ViewHolder
{
private HashMap<Integer, View> storedViews = new HashMap<Integer, View>();
public ViewHolder addView(View view)
{
int id = view.getId();
storedViews.put(id, view);
return this;
}
public View getView(int id)
{
return storedViews.get(id);
}
}
}
Public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Obtém a referência da ExpandableListView
ExpandableListView expListView = (ExpandableListView) findViewById(R.id.expandableListView);
//Obtém a lista de perguntas a ser apresentada
final ArrayList<Question> questions = getQuestions();
//Cria uma instância do adapter e atribui-o à ExpandableListView
expListView.setAdapter(new ExpandListAdapter(this, questions));
//Define um listener para tratar a selecção das respostas
expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
//Indica que esta resposta foi seleccionada
questions.get(groupPosition).setSelectedAnswer(childPosition);
//Obtém a referência do adapter
ExpandListAdapter adapter = (ExpandListAdapter) parent.getExpandableListAdapter();
//Notifica o adapter da selecção para que ela seja representada visualmente
adapter.notifyDataSetChanged();
return true;
}
});
}
//Preenche um ArrayList com 10 perguntas e respectivas respostas
private ArrayList<Question> getQuestions() {
ArrayList<Question> questions = new ArrayList<>();
Question question;
int totalAnswers;
Random rnd = new Random();
for (int i = 1; i <= 10; i++){
question = new Question("Question - " + i);
//As perguntas pares têm 3 respostas as impar 5
if(i%2 == 0){
totalAnswers = 3;
}else{
totalAnswers = 5;
}
for (int j = 1; j <= totalAnswers; j++){
question.addAnswer("Answer - " + j + " to question - " + i);
}
//Atribui aleatóriamente a resposta correcta
question.setCorrectAnswer(rnd.nextInt(totalAnswers));
questions.add(question);
}
return questions;
}
}
//Responsável por guardar o texto da pergunta, as respostas, a resposta correcta e a resposta seleccionada
public class Question {
private final String questionText;
private ArrayList<Answer> answers;
private int selectedAnswer = -1;
private int correctAnswer = -1;
public Question(String text) {
this.questionText = text;
answers = new ArrayList<>();
}
public boolean isCorrectlyAnswered(){
return correctAnswer == getSelectedAnswer();
}
public int getSelectedAnswer() {
return selectedAnswer;
}
public void setSelectedAnswer(int selectedAnswer) {
this.selectedAnswer = selectedAnswer;
}
public void setCorrectAnswer(int correctAnswer) {
if(answers.size() <= correctAnswer){
throw new IllegalArgumentException();
}
this.correctAnswer = correctAnswer;
}
public void addAnswer(String text){
answers.add(new Answer(text));
}
public String getText(){
return questionText;
}
public ArrayList<Answer> getAnswers(){
return answers;
}
}
<!-- View para as perguntas, representa cada um dos grupos da ExpandableListView.-->
<!-- Contém o texto da pergunta e um sinal para indicar se a pergunta foi correctamente respondida.-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="75dp"
card_view:cardCornerRadius="4dp">
<TextView
android:id="@+id/questionText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="questionText"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/correctMark"
android:layout_gravity="right"
android:clickable="false"
android:focusable="false"
android:checked="true"
android:visibility="gone"/>
</android.support.v7.widget.CardView>
</LinearLayout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment