Search code examples
androidlistviewandroid-arrayadaptercustom-adapter

How to create multiple layout ListViews with CustomAdapter in Android Studio


I am trying to create an Quiz in Android Studio. Therefore I want to implement a ListView which displays the question in a TextView and the answer in form of Buttons.

The multiple layouts are needed because a question can have two, three or four answers (Buttons). So in every row there should be a TextView and depending on the answers 2, 3 or 4 Buttons.

This is my CustomAdapter so far. The problem is that this only works for one TextView and I don't know how i can adress the Buttons.

public class CustomAdapter extends ArrayAdapter {
private QuizItem[] items;

@Override
public int getViewTypeCount() {
    return 3;
}

@Override
public int getItemViewType(int position) {
    return items[position].getCategory();
}

public CustomAdapter(Context context, int question, QuizItem[] items) {
    super(context, question, items);
    this.items = items;
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder = null;
    QuizItem quizItem = items[position];
    int quizItemType = getItemViewType(position);

    if (convertView == null) {

        if (quizItemType == Config.CATEGORY_TWO_ANSWERS) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.two_answers, null);
        } else if (quizItemType == Config.CATEGORY_THREE_ANSWERS) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.three_answers, null);
        }
        else{
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.four_answers, null);
        }

        TextView textView = (TextView) convertView.findViewById(R.id.textView);
        viewHolder = new ViewHolder(textView);

        convertView.setTag(viewHolder);

    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    viewHolder.getText().setText(quizItem.getQuestion());
    return convertView;
}}

And this is my Main Class where I create some demo date with the for loop:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ListView listView = (ListView) findViewById(R.id.simpleListView);
    final QuizItem[] itemArray = new QuizItem[10];
    int toggle = 0;

    for(int i = 0; i < itemArray.length; i++){

        if(toggle == 0){

            itemArray[i] = new QuizItem("Question " + i, "Answer A", "Answer B");
            toggle = 1;
        }
        else if(toggle == 1){

            itemArray[i] = new QuizItem("Question " + i, "Answer A", "Answer B", "Answer C");
            toggle = 2;
        }
        else{
            itemArray[i] = new QuizItem("Question " + i, "Answer A", "Answer B", "Answer C", "Answer D");
            toggle = 0;
        }
    }

    CustomAdapter customAdapter = new CustomAdapter(this, R.id.textView, itemArray);
    listView.setAdapter(customAdapter);

}}

So how can put the answer text on the Buttons and display the right amount of Buttons? I'm very thankful for every information!

EDIT: This is the LogCat

03-28 14:58:48.564  12092-12092/adonis.quiz D/dalvikvm﹕ Late-enabling CheckJNI
03-28 14:58:48.564  12092-12092/adonis.quiz D/dalvikvm﹕ Try to disable coredump for pid 12092
03-28 14:58:48.564  12092-12092/adonis.quiz D/dalvikvm﹕ Process 12092 nice name: adonis.quiz
03-28 14:58:48.564  12092-12092/adonis.quiz D/dalvikvm﹕ Extra Options: not specified
03-28 14:58:48.684  12092-12092/adonis.quiz W/dalvikvm﹕ VFY: unable to find class referenced in signature (Landroid/view/SearchEvent;)
03-28 14:58:48.684  12092-12092/adonis.quiz I/dalvikvm﹕ Could not find method android.view.Window$Callback.onSearchRequested, referenced from method android.support.v7.view.WindowCallbackWrapper.onSearchRequested
03-28 14:58:48.684  12092-12092/adonis.quiz W/dalvikvm﹕ VFY: unable to resolve interface method 14571: Landroid/view/Window$Callback;.onSearchRequested (Landroid/view/SearchEvent;)Z
03-28 14:58:48.684  12092-12092/adonis.quiz D/dalvikvm﹕ VFY: replacing opcode 0x72 at 0x0002
03-28 14:58:48.684  12092-12092/adonis.quiz I/dalvikvm﹕ Could not find method android.view.Window$Callback.onWindowStartingActionMode, referenced from method android.support.v7.view.WindowCallbackWrapper.onWindowStartingActionMode
03-28 14:58:48.684  12092-12092/adonis.quiz W/dalvikvm﹕ VFY: unable to resolve interface method 14575: Landroid/view/Window$Callback;.onWindowStartingActionMode (Landroid/view/ActionMode$Callback;I)Landroid/view/ActionMode;
03-28 14:58:48.684  12092-12092/adonis.quiz D/dalvikvm﹕ VFY: replacing opcode 0x72 at 0x0002
03-28 14:58:48.714  12092-12092/adonis.quiz I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getChangingConfigurations, referenced from method android.support.v7.widget.TintTypedArray.getChangingConfigurations
03-28 14:58:48.714  12092-12092/adonis.quiz W/dalvikvm﹕ VFY: unable to resolve virtual method 463: Landroid/content/res/TypedArray;.getChangingConfigurations ()I
03-28 14:58:48.714  12092-12092/adonis.quiz D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002
03-28 14:58:48.724  12092-12092/adonis.quiz I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getType, referenced from method android.support.v7.widget.TintTypedArray.getType
03-28 14:58:48.724  12092-12092/adonis.quiz W/dalvikvm﹕ VFY: unable to resolve virtual method 485: Landroid/content/res/TypedArray;.getType (I)I
03-28 14:58:48.724  12092-12092/adonis.quiz D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002
03-28 14:58:48.804  12092-12092/adonis.quiz D/CA/getType﹕ 5
03-28 14:58:48.804  12092-12092/adonis.quiz D/CA/getType﹕ 5
03-28 14:58:48.814  12092-12092/adonis.quiz D/AndroidRuntime﹕ Shutting down VM
03-28 14:58:48.814  12092-12092/adonis.quiz W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x430f2140)
03-28 14:58:48.824  12092-12092/adonis.quiz E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: adonis.quiz, PID: 12092
    java.lang.NullPointerException
            at adonis.quiz.CustomAdapter.getView(CustomAdapter.java:65)
            at android.widget.AbsListView.obtainView(AbsListView.java:2312)
            at android.widget.ListView.measureHeightOfChildren(ListView.java:1263)
            at android.widget.ListView.onMeasure(ListView.java:1175)
            at android.view.View.measure(View.java:16772)
            at android.widget.RelativeLayout.measureChild(RelativeLayout.java:689)
            at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:473)
            at android.view.View.measure(View.java:16772)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5139)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
            at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
            at android.view.View.measure(View.java:16772)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5139)
            at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:391)
            at android.view.View.measure(View.java:16772)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5139)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
            at android.view.View.measure(View.java:16772)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5139)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
            at android.view.View.measure(View.java:16772)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5139)
            at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2294)
            at android.view.View.measure(View.java:16772)
            at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1936)
            at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1133)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1315)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1020)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5762)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:771)
            at android.view.Choreographer.doCallbacks(Choreographer.java:574)
            at android.view.Choreographer.doFrame(Choreographer.java:544)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:757)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:149)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
            at dalvik.system.NativeStart.main(Native Method)

Solution

  • /-------------------QuizItem Model------------------/

       public class QuizItem {
    
        public String strQues = "";
        public int iNoOfAns = 0;
        public String strAns1 = "";
        public String strAns2 = "";
        public String strAns3 = "";
        public String strAns4 = "";
    
        public QuizItem (int noOFAns,String ques,String ans1,String ans2,String ans3,String ans4)
        {
    
            this.iNoOfAns = noOFAns;
            this.strQues = ques;
            this.strAns1 = ans1;
            this.strAns2 = ans2;
            this.strAns3 = ans3;
            this.strAns4 = ans4;
    
        }
    
    }
    

    Make few change while creating array, I have added no. of ans parameter-

             final QuizItem[] itemArray = new QuizItem[10];
                int toggle = 0;
    
                for(int i = 0; i < itemArray.length; i++){
    
                    if(toggle == 0){
    
                        itemArray[i] = new QuizItem(2,"Question " + i, "Answer A", "Answer B","","");
                        toggle = 1;
                    }
                    else if(toggle == 1){
    
                        itemArray[i] = new QuizItem(3,"Question " + i, "Answer A", "Answer B", "Answer C","");
                        toggle = 2;
                    }
                    else{
                        itemArray[i] = new QuizItem(4,"Question " + i, "Answer A", "Answer B", "Answer C", "Answer D");
                        toggle = 0;
                    }
                }
    

    /-------------------CustomAdapter -------------------------/

     public class CustomAdapter extends ArrayAdapter<QuizItem> {
        private QuizItem[] items;
    
        Context mContext;
    
        public CustomAdapter(Context context, int resource, QuizItem[] objects) {
            super(context, resource, objects);
            mContext = context;
            items = objects;
    
        }
    
    
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
    
            QuizItem quizItem = items[position];
            int quizItemType = quizItem.iNoOfAns;
            LayoutInflater inflator = ((android.app.Activity) mContext)
                    .getLayoutInflater();
    
    
    
                if (quizItemType == 2) {
    
                    convertView = inflator.inflate(R.layout.temp_ans_two, parent,false);
    
    
                    TextView textView = (TextView) convertView.findViewById(R.id.tv_ques);
                    textView.setText(quizItem.strQues);
    
                    Button button1 = (Button)convertView.findViewById(R.id.button1);
                    button1.setText(quizItem.strAns1);
    
                    Button button2 = (Button)convertView.findViewById(R.id.button2);
                    button2.setText(quizItem.strAns2);
    
    
    
                } else if (quizItemType ==3) {
    
                    convertView = inflator.inflate(R.layout.temp_ans_three, parent,false);
    
                    TextView textView = (TextView) convertView.findViewById(R.id.tv_ques);
                    textView.setText(quizItem.strQues);
    
                    Button button1 = (Button)convertView.findViewById(R.id.button1);
                    button1.setText(quizItem.strAns1);
    
                    Button button2 = (Button)convertView.findViewById(R.id.button2);
                    button2.setText(quizItem.strAns2);
    
                    Button button3 = (Button)convertView.findViewById(R.id.button3);
                    button3.setText(quizItem.strAns3);
    
    
                }
                else{
                    convertView = inflator.inflate(R.layout.temp_ans_four, parent,false);
    
                    TextView textView = (TextView) convertView.findViewById(R.id.tv_ques);
                    textView.setText(quizItem.strQues);
    
                    Button button1 = (Button)convertView.findViewById(R.id.button1);
                    button1.setText(quizItem.strAns1);
    
                    Button button2 = (Button)convertView.findViewById(R.id.button2);
                    button2.setText(quizItem.strAns2);
    
                    Button button3 = (Button)convertView.findViewById(R.id.button3);
                    button3.setText(quizItem.strAns3);
    
                    Button button4 = (Button)convertView.findViewById(R.id.button4);
                    button4.setText(quizItem.strAns4);
    
                }
    
    
            return convertView;
        }}