title: Getting conflicting ClassCastException when calling getChildAt from LinearLayout
body: <p>The system I'm currently working on relies on the layout being built from a <code>JsonArray</code> returned from an API, it does this by primarily using several different <code>ViewHolder</code>s in the adapter class.</p>
  
  <p>The problem I'm having is trying to build a <code>RadioGroup</code> that can only have one option selected at once. The code for that is below.</p>
  
  <pre><code>public class RadioGroupModule extends View implements View.OnClickListener{
  
      private JSONObject jsonObject;
      private Context context;
      private RadioGroupInterface radioGroupInterface;
  
      private LinearLayout parentLayout, ll_radio_group;
      private ImageView img_radio_group;
      private TextView txt_radio_group_text;
  
      public RadioGroupModule(JSONObject jsonObject, LinearLayout parentLayout, Context context,
                              RadioGroupInterface radioGroupInterface){
          super(context);
          this.jsonObject = jsonObject;
          this.parentLayout = parentLayout;
          this.context = context;
          this.radioGroupInterface = radioGroupInterface;
  
          renderView(parentLayout);
      }
  
      public void renderView(LinearLayout parentLayout){
          LayoutInflater inflater = LayoutInflater.from(context);
          View view = inflater.inflate(R.layout.module_radio_group, parentLayout, false);
  
          //Logic shit yo
  
          setUpLinearLayout(view);
          setUpTextView(view);
          setUpImageView(view);
  
          parentLayout.addView(view);
      }
  
      private void setUpLinearLayout(View view){
          ll_radio_group = (LinearLayout)view.findViewById(R.id.ll_radio_group);
          ll_radio_group.setOnClickListener(this);
      }
  
      private void setUpImageView(View view){
          img_radio_group = (ImageView)view.findViewById(R.id.img_radio_group);
          img_radio_group.setOnClickListener(this);
  
          try{
              if(jsonObject.has("selected")){
                  if(jsonObject.getBoolean("selected")){
                      setSelectedTrue();
                  } else {
                      setSelectedFalse();
                  }
              } else {
                  setSelectedFalse();
              }
          } catch (Exception e){
              e.printStackTrace();
          }
      }
  
      private void setUpTextView(View view){
          txt_radio_group_text = (TextView)view.findViewById(R.id.txt_radio_group_text);
          txt_radio_group_text.setOnClickListener(this);
  
          try{
              txt_radio_group_text.setText(jsonObject.getString("label"));
          } catch (Exception e){
              e.printStackTrace();
          }
      }
  
      public JSONObject getJsonObject(){
          return jsonObject;
      }
  
      public void setSelectedTrue(){
          txt_radio_group_text.setBackgroundColor(context.getResources().getColor(R.color.black));
          txt_radio_group_text.setTextColor(context.getResources().getColor(android.R.color.white));
      }
  
      public void setSelectedFalse(){
          txt_radio_group_text.setBackgroundColor(context.getResources().getColor(android.R.color.white));
          txt_radio_group_text.setTextColor(context.getResources().getColor(R.color.black));
      }
  
      @Override
      public void onClick(View v) {
          try{
              jsonObject.put("selected", true);
          } catch (Exception e){
              e.printStackTrace();
          }
          radioGroupInterface.returnUpdatedObject(jsonObject);
      }
  }
  </code></pre>
  
  <p>The view is then added to a <code>LinearLayout</code> in a <code>View</code> that holds the <code>RadioGroupModule</code>, the XML for that view is below.</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:clickable="true"&gt;
  
      &lt;TextView
          android:id="@+id/txt_radio_group_title"
          android:layout_width="match_parent"
          android:layout_height="50dp"
          android:gravity="center"
          android:textColor="@color/black"/&gt;
  
      &lt;LinearLayout
          android:id="@+id/ll_radio_group_holder"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:orientation="vertical"/&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>The module is added to that linear layout like so, <code>setPayload</code> is called from <code>onBindViewHolder</code> after <code>getItemViewType</code> is called.</p>
  
  <pre><code>public void setPayload(JSONObject jsonObject){
  
      this.jsonObject = jsonObject;
      answerArray.put(jsonObject);
  
      try{
          txt_radio_group_title.setText(jsonObject.getString("label"));
          valuesArray = jsonObject.getJSONArray("values");
  
          for(int i = 0; i &lt; valuesArray.length(); i++){
              JSONObject object = valuesArray.getJSONObject(i);
              ll_radio_group_holder.addView(new RadioGroupModule(object, ll_radio_group_holder, context, new RadioGroupInterface() {
                  @Override
                  public void returnUpdatedObject(JSONObject jsonObject) {
  
                      for(int i = 0; i &lt; valuesArray.length(); i++){
  
                          try{
                              JSONObject valueObject = valuesArray.getJSONObject(i);
                              if(valueObject.getInt("id") == jsonObject.getInt("id")){
                                  valueObject.put("selected", jsonObject.getBoolean("selected"));
                                  setValuesAsFalse(valueObject);
                              }
  
                          } catch (Exception e){
                              e.printStackTrace();
                          }
                      }
                  }
              }));
          }
  
      } catch (Exception e){
          e.printStackTrace();
      }
  }
  </code></pre>
  
  <p>The module is added the the linear layout no problem. The problem occurs when I'm calling <code>getChildAt</code> from the module holder <code>LinearLayout</code> and trying to cast it <code>RadioGroupModule</code>. The modules constructor passes in an interface that is used for callback when the user clicks on a the Module in the <code>LinearLayout</code>. </p>
  
  <p>The callback passes back the <code>JSONObject</code> that has been selected. From there I need to loop through a <code>JSONArray</code> of all the results and put the selected value to false in all the other objects, and change an ImageViews source to not selected if it was previously selected, this is where the problems arise. Below this is the method I've written to do this and the <code>JSONArray</code> of the checkboxes.</p>
  
  <pre><code>public void setValuesAsFalse(JSONObject correctObject) throws Exception{
      JSONArray jsonArray = jsonObject.getJSONArray("values");
      for(int i = 0; i &lt; jsonArray.length(); i++){
          JSONObject valueObject = jsonArray.getJSONObject(i);
          if(valueObject.getInt("id") != correctObject.getInt("id")){
              valueObject.put("selected", false);
              RadioGroupModule radioGroupModule = (RadioGroupModule) ll_radio_group_holder.getChildAt(i);
          }
      }
  }
  </code></pre>
  
  <p>And the values array.</p>
  
  <pre><code>[
    {
      "label": "Option 1",
      "value": "option-1",
      "selected": true,
      "id": 31
    },
    {
      "label": "Option 2",
      "value": "option-2",
      "id": 32,
    },
    {
      "label": "Option 3",
      "value": "option-3",
      "id": 33
    },
    {
      "label": "option-4",
      "value": "option 4",
      "id": 34
    }
  ]
  </code></pre>
  
  <p>That method throws the following <code>ClassCastException</code></p>
  
  <pre><code>java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to com.unisaas.unisaas.risk_assessment.modules.RadioGroupModule
  04-18 12:12:47.318 2201-2201/com.unisaas.unisaas W/System.err:     at com.unisaas.unisaas.risk_assessment.risk_assesment_fragment.RiskFormAdapter$RadioGroupViewHolder.setValuesAsFalse(RiskFormAdapter.java:606)
  04-18 12:12:47.319 2201-2201/com.unisaas.unisaas W/System.err:     at com.unisaas.unisaas.risk_assessment.risk_assesment_fragment.RiskFormAdapter$RadioGroupViewHolder$1.returnUpdatedObject(RiskFormAdapter.java:582)
  04-18 12:12:47.319 2201-2201/com.unisaas.unisaas W/System.err:     at com.unisaas.unisaas.risk_assessment.modules.RadioGroupModule.onClick(RadioGroupModule.java:112)
  04-18 12:12:47.319 2201-2201/com.unisaas.unisaas W/System.err:     at android.view.View.performClick(View.java:5609)
  04-18 12:12:47.319 2201-2201/com.unisaas.unisaas W/System.err:     at android.view.View$PerformClick.run(View.java:22262)
  04-18 12:12:47.319 2201-2201/com.unisaas.unisaas W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
  04-18 12:12:47.319 2201-2201/com.unisaas.unisaas W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
  04-18 12:12:47.319 2201-2201/com.unisaas.unisaas W/System.err:     at android.os.Looper.loop(Looper.java:154)
  04-18 12:12:47.319 2201-2201/com.unisaas.unisaas W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6077)
  04-18 12:12:47.319 2201-2201/com.unisaas.unisaas W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
  04-18 12:12:47.319 2201-2201/com.unisaas.unisaas W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
  04-18 12:12:47.319 2201-2201/com.unisaas.unisaas W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
  </code></pre>
  
  <p>For arguments sake I changed this line</p>
  
  <pre><code>RadioGroupModule radioGroupModule = (RadioGroupModule) ll_radio_group_holder.getChildAt(i);
  </code></pre>
  
  <p>to </p>
  
  <pre><code>LinearLayout linearLayout = (LinearLayout) ll_radio_group_holder.getChildAt(i);
  </code></pre>
  
  <p>and the following exception was thrown</p>
  
  <pre><code>04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err: java.lang.ClassCastException: com.unisaas.unisaas.risk_assessment.modules.RadioGroupModule cannot be cast to android.widget.LinearLayout
  04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err:     at com.unisaas.unisaas.risk_assessment.risk_assesment_fragment.RiskFormAdapter$RadioGroupViewHolder.setValuesAsFalse(RiskFormAdapter.java:606)
  04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err:     at com.unisaas.unisaas.risk_assessment.risk_assesment_fragment.RiskFormAdapter$RadioGroupViewHolder$1.returnUpdatedObject(RiskFormAdapter.java:582)
  04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err:     at com.unisaas.unisaas.risk_assessment.modules.RadioGroupModule.onClick(RadioGroupModule.java:112)
  04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err:     at android.view.View.performClick(View.java:5609)
  04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err:     at android.view.View$PerformClick.run(View.java:22262)
  04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
  04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
  04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err:     at android.os.Looper.loop(Looper.java:154)
  04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6077)
  04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
  04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
  04-18 12:38:25.965 26129-26129/com.unisaas.unisaas W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
  </code></pre>
  
  <p>So the <code>LinearLayout</code> that holds the <code>RadioGroupModule</code> does actually contain <code>RadioGroupModule</code> but they cannot be cast when calling <code>getChildAt</code>. The reason I want the <code>RadioGroupModule</code> at position is so that I can call <code>setSelected</code> false which will change the <code>TextView</code> backgroud colour and eventually the <code>ImageView</code> source when I get the asset.</p>
  
  <p>Can anyone see a possible solution to this? Or is it not possible to do it this way?</p>
  
  <p>Cheers for any help!</p>
  
  <p>Edit:</p>
  
  <p>I forgot to put the XML for the front end of the <code>RadioGroupModule</code>, it's below this.</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout
      android:id="@+id/ll_radio_group"
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:clickable="true"&gt;
  
      &lt;ImageView
          android:id="@+id/img_radio_group"
          android:layout_width="60dp"
          android:layout_height="60dp" /&gt;
  
      &lt;TextView
          android:id="@+id/txt_radio_group_text"
          android:layout_width="match_parent"
          android:layout_height="60dp"
          android:textSize="22sp"
          android:gravity="center_vertical"
          android:paddingLeft="10dp"/&gt;
  
  &lt;/LinearLayout&gt;
  </code></pre>