Search code examples
androidlistviewexpandablelistviewlayout-inflaterexpandablelistadapter

Android Expandable listview with radio button


Am using an API to fill up a questionnaire App in android. Am using expandable listview , based on the API I get question category (Parent)and questions(child). Question(child) may change based on the question type.(Objective type : Radiobutton, yes or no, Text Type: Edit text).

I have statically created a custom layout XML and inflate that layout in getChildView method or expandable listview.

but when I expand/collapse the expandable list view all the radio button selection go wrong. eg: if I answer for 1st category child, it will also be answered for some other category.

Please get me a solution for this. Do I have to create the Radio button / radio group dynamically or this is enough. Based on the questionType i hide/show the widgets. Please find the code below.

My HashMap value is like :

HashMap<String, ArrayList<QListModel>> expandableListDetail = new HashMap<>();

ArrayList Contains :Question,QuestionType,QuestionId etc

Here is my code : My Adapter Class

import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;

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


public class ExpandableListAdapter extends BaseExpandableListAdapter {

    private Context context;
    private List<String> expandableListTitle;
    private HashMap<String, ArrayList<QListModel>> expandableListDetail;

    public ExpandableListAdapter(Context context, List<String> expandableListTitle, HashMap<String,
            ArrayList<QListModel>> expandableListDetail) {
        this.context = context;
        this.expandableListTitle = expandableListTitle;
        this.expandableListDetail = expandableListDetail;
    }


    @Override
    public int getGroupCount() {
        return this.expandableListTitle.size();
    }

    @Override
    public int getChildrenCount(int listPosition) {
//        return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
//                .size();
        Log.e("VCVCV",String.valueOf(this.expandableListDetail.get(this.expandableListTitle.get(listPosition)).size()));

        return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
                .size();

    }

    @Override
    public Object getGroup(int listPosition) {
        return this.expandableListTitle.get(listPosition);
    }

    @Override
    public Object getChild(int listPosition, int expandedListPosition) {
        return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
                .get(expandedListPosition);
    }

    @Override
    public long getGroupId(int listPosition) {
        return listPosition;
    }

    @Override
    public long getChildId(int listPosition, int expandedListPosition) {
        return expandedListPosition;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int listPosition, boolean isExpanded,
                             View convertView, ViewGroup parent) {
        String listTitle = (String) getGroup(listPosition);
        if (convertView == null) {
            LayoutInflater layoutInflater = (LayoutInflater) this.context.
                    getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.expand_parent, null);
        }
        TextView listTitleTextView = (TextView) convertView
                .findViewById(R.id.groupText);
        listTitleTextView.setText(listTitle);




        return convertView;
    }

    @Override
    public View getChildView(int listPosition, final int expandedListPosition,
                             boolean isLastChild, View convertView, ViewGroup parent) {
       QListModel expandedListText = (QListModel) getChild(listPosition, expandedListPosition);

        Log.e("ChildQuestions",expandedListText.getqList());

        if (convertView == null) {
            LayoutInflater layoutInflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.expand_child_selection, null);
        }


        TextView expandedListTextView = (TextView) convertView.findViewById(R.id.childText);
        EditText expandedListEditText = (EditText) convertView.findViewById(R.id.editTextAdditional);
        expandedListTextView.setText(expandedListText.getqList());

        RadioGroup rgp = (RadioGroup) convertView.findViewById(R.id.radioGroup);

        //NotUsing
        RadioButton radioYes=(RadioButton) convertView.findViewById(R.id.radioYes);
        RadioButton radioNo=(RadioButton) convertView.findViewById(R.id.radioNo);

           if (expandedListText.getqType().equals("Y/N")){
               rgp.setVisibility(View.VISIBLE);
               expandedListEditText.setVisibility(View.GONE);
           }
            else {
               expandedListEditText.setVisibility(View.VISIBLE);
               rgp.setVisibility(View.GONE);
           }



        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}

My Layout

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

    <TextView
        android:id="@+id/childText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:textColor="@color/colorBlackLight"
        android:text=""/>


            <RadioGroup
            android:id="@+id/radioGroup"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
                <RadioButton
                    android:id="@+id/radioYes"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/colorBlackLight"
                android:text="Yes"/>
                <RadioButton
                    android:id="@+id/radioNo"
                android:layout_marginLeft="20dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/colorBlackLight"
                android:text="No"/>
            </RadioGroup>


    <EditText
        android:id="@+id/editTextAdditional"
        android:layout_width="match_parent"
        android:padding="5dp"
        android:textColor="@color/colorBlackLight"
        android:layout_marginBottom="10dp"
        android:layout_marginRight="20dp"
        android:background="@color/colorFrameBLueLight"
        android:textSize="12sp"
        android:layout_height="wrap_content" />





</LinearLayout>

Problem: If i make a selection in first category in all category item is selected, Do i have to manage the radio button and radio group dynamically? If so in which method i have to do that. If I Create them in getChildView it will be called each time i expand a category. So previous selection will not be remembered. Please get me a solution. Thanks in advance.


Solution

  • // Below code

    public class RecyclerViewQuest extends RecyclerView.Adapter<RecyclerViewQuest.MyViewHolder> {
    
        private Context context;
        private ArrayList<QuestModel> questModelArrayList;
        private int position;
        private ArrayList<Model> checkArrayList=new ArrayList<>();
        private SparseIntArray mSelections,mDisabled;
        private String temptitle="";
        private CallbackInterface mCallbackInterface;
        private ArrayList<QuestModel> answerArrayList= new ArrayList<>();
        private ArrayList<ViewLayout> arrayList;
        private HashMap<Integer,ArrayList<ViewLayout>> inputLayoutHashMap= new HashMap<>();
    
        public interface CallbackInterface{
            void onMethodCallback(QuestModel questModel,RecyclerViewQuest.RequestBack requestBack);
        }
    
        public interface RequestBack{
            void onReceive(boolean status);
        }
    
        public RecyclerViewQuest(Context context, ArrayList<QuestModel> questModelArrayList,CallbackInterface mCallbackInterface) {
            this.context = context;
            this.questModelArrayList = questModelArrayList;
            mSelections = new SparseIntArray();
            mDisabled= new SparseIntArray();
            this.mCallbackInterface=mCallbackInterface;
        }
    
    
        @Override
        public RecyclerViewQuest.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.quest_recycler, parent, false);
            RecyclerViewQuest.MyViewHolder holder = new RecyclerViewQuest.MyViewHolder(itemView,questModelArrayList,context);
            return holder;
        }
    
        @Override
        public void onBindViewHolder(final RecyclerViewQuest.MyViewHolder holder, final int position) {
    
            final QuestModel questModel=questModelArrayList.get(position);
            try {
                if (questModelArrayList.get(position - 1).getSurvycat().equals(questModelArrayList.get(position).getSurvycat())) {
                    holder.categoryName.setVisibility(View.GONE);
                }else {
                    holder.categoryName.setVisibility(View.VISIBLE);
                    holder.categoryName.setText(questModelArrayList.get(position).getSurvycat());
                }
            }catch (ArrayIndexOutOfBoundsException e){
                holder.categoryName.setVisibility(View.VISIBLE);
                holder.categoryName.setText(questModelArrayList.get(position).getSurvycat());
            }
    
            holder.categoryName.setText(questModel.getSurvycat());
            if(questModel.getQformat().equals("Y/N")){
                holder.radioGroupQuest.setTag(questModelArrayList.get(position));
                holder.radioText.setText(questModel.getQlist());
                holder.layoutRadio.setVisibility(View.VISIBLE);
                holder.layoutEditText.setVisibility(View.GONE);
            }else {
                holder.editTextText.setText(questModel.getQlist());
                holder.layoutRadio.setVisibility(View.GONE);
                holder.layoutEditText.setVisibility(View.VISIBLE);
            }
    
            holder.radioText.setTypeface(holder.questList);
            holder.editTextText.setTypeface(holder.questList);
            holder.radioYes.setTypeface(holder.questList);
            holder.radioNo.setTypeface(holder.questList);
            holder.categoryName.setTypeface(holder.questCat);
            holder.editTextAdd.setTypeface(holder.questList);
            holder.submitTextview.setTypeface(holder.questCat);
    
            holder.radioGroupQuest.setOnCheckedChangeListener(null);
    
            //Check and Uncheck Radiobutton
            holder.radioGroupQuest.clearCheck();
            if(mSelections.get(position) > -1) {
               holder.radioGroupQuest.check(mSelections.get(position));
            }
    
            //Enabling and disabling radio buttons
            for(int i = 0; i < holder.radioGroupQuest.getChildCount(); i++){
                holder.radioGroupQuest.getChildAt(i).setEnabled(true);
            }
            if(mDisabled.get(position) > 0) {
                RadioGroup rg= (RadioGroup)holder.radioGroupQuest.findViewById(mDisabled.get(position));
                for (int i = 0; i < rg.getChildCount(); i++) {
                    rg.getChildAt(i).setEnabled(false);
                }
            }
    
    
            //Clearing and binding EditText
            for (int i=0;i<holder.inputLayout.getChildCount();i++){
                View v= holder.inputLayout.getChildAt(i);
                if (v instanceof ImageView) {
                    holder.iconComplete.setVisibility(View.GONE);
                }else if(v instanceof EditText){
                    holder.editTextAdd.setText("");
                    holder.editTextAdd.setHint("Comment here and click submit button");
                }else if(v instanceof TextView){
                    holder.submitTextview.setVisibility(View.VISIBLE);
                }
            }
    
            if(inputLayoutHashMap.size()>0){
                try{
                ViewLayout viewLayout=inputLayoutHashMap.get(position).get(0);
    
    
                    holder.submitTextview.setVisibility(View.GONE);
                    holder.editTextAdd.setText(viewLayout.getEditTextValue());
                    holder.editTextAdd.setEnabled(false);
                    holder.iconComplete.setVisibility(View.VISIBLE);
    
                }
                catch (NullPointerException ex){
                    Log.e("NUL","Null");
                }
            }
    
            holder.submitTextview.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    ViewLayout viewLayout= new ViewLayout();
                    QuestModel questModelResult=questModelArrayList.get(position);
                    questModelResult.setResult(holder.editTextAdd.getText().toString());
                    questModelResult.setPosition(position);
    
    
    
                    viewLayout.setEditTextId(holder.editTextAdd.getId());
                    viewLayout.setEditTextValue(holder.editTextAdd.getText().toString());
                    viewLayout.setLayoutId(holder.layoutEditText.getId());
                    arrayList= new ArrayList<>();
                    arrayList.add(viewLayout);
    
                    mCallbackInterface.onMethodCallback(questModelResult, new RequestBack() {
                        @Override
                        public void onReceive(boolean status) {
                            holder.submitTextview.setVisibility(View.GONE);
                            holder.editTextAdd.setEnabled(false);
                            holder.iconComplete.setVisibility(View.VISIBLE);
                            inputLayoutHashMap.put(position,arrayList);
                        }
                    });
    
                    holder.radioGroupQuest.setTag(position);
    
                }
            });
    
            holder.radioGroupQuest.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(final RadioGroup group, @IdRes int checkedId) {
                    RadioButton radioButton=(RadioButton) group.findViewById(checkedId);
    
                    mSelections.put(position, group.getCheckedRadioButtonId());
    
                    QuestModel questModelResult=questModelArrayList.get(position);
                    questModelResult.setResult(radioButton.getText().toString());
    
    
    
                    mCallbackInterface.onMethodCallback(questModelResult, new RequestBack() {
                        @Override
                        public void onReceive(boolean status) {
                            if(status){
                                mDisabled.put(position,group.getId());
                                for (int i = 0; i < group.getChildCount(); i++) {
                                    group.getChildAt(i).setEnabled(false);
    
                                }
                            }
                        }
                    });
                }
            });
        }
    
        public ArrayList<QuestModel> getAnswerArrayList(){
            return answerArrayList;
        }
    
        public class MyViewHolder extends RecyclerView.ViewHolder {
            ArrayList<QuestModel> questModelArrayList= new ArrayList<>();
            Context context;
            private RadioGroup radioGroupQuest;
            private RadioButton radioYes,radioNo;
            private EditText editTextAdd;
            private TextView categoryName,submitTextview,radioText,editTextText;
            private RelativeLayout layoutRadio,layoutEditText;
            private Typeface questList,questCat;
            private ImageView iconComplete;
            private LinearLayout inputLayout;
    
            public MyViewHolder(View itemView, final ArrayList<QuestModel> questModelArrayList, Context context) {
                super(itemView);
    
                this.questModelArrayList=questModelArrayList;
                this.context=context;
    
                layoutRadio=(RelativeLayout)itemView.findViewById(R.id.radioLayout);
                layoutEditText=(RelativeLayout)itemView.findViewById(R.id.editTextLayout);
    
                radioGroupQuest=(RadioGroup) itemView.findViewById(R.id.radio_group_recycler);
                radioYes=(RadioButton)itemView.findViewById(R.id.radioYes);
                radioNo=(RadioButton)itemView.findViewById(R.id.radioNo);
    
                inputLayout=(LinearLayout)itemView.findViewById(R.id.inputLayout);
    
                categoryName=(TextView)itemView.findViewById(R.id.categoryName);
                radioText=(TextView)itemView.findViewById(R.id.radioText);
                editTextText=(TextView)itemView.findViewById(R.id.editTextText);
                submitTextview=(TextView)itemView.findViewById(R.id.submitTextview);
    
                radioYes=(RadioButton)itemView.findViewById(R.id.radioYes);
                radioNo=(RadioButton)itemView.findViewById(R.id.radioNo);
    
                iconComplete=(ImageView)itemView.findViewById(R.id.iconComplete);
    
                editTextAdd=(EditText)itemView.findViewById(R.id.editTextAdd);
                questList = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto_Light.ttf");
                questCat = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto_Regular.ttf");
            }
        }
    
        @Override
        public int getItemCount() {
         return questModelArrayList.size();
        }
    
        @Override
        public int getItemViewType(int position) {
            return super.getItemViewType(position);
        }
    
        @Override
        public long getItemId(int position) {
            return super.getItemId(position);
        }
    }