2017-04-18 58 views
1

我目前正在使用的系統依賴於從API返回的JsonArray構建的佈局,它主要通過在適配器類中使用幾個不同的ViewHolder來執行此操作。從LinearLayout調用getChildAt時獲取衝突ClassCastException

我遇到的問題是試圖建立一個RadioGroup,一次只能選擇一個選項。代碼如下。

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); 
    } 
} 

該視圖然後加至LinearLayoutView保持所述RadioGroupModule,該視圖的XML如下。

<?xml version="1.0" encoding="utf-8"?> 
<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"> 

    <TextView 
     android:id="@+id/txt_radio_group_title" 
     android:layout_width="match_parent" 
     android:layout_height="50dp" 
     android:gravity="center" 
     android:textColor="@color/black"/> 

    <LinearLayout 
     android:id="@+id/ll_radio_group_holder" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical"/> 

</LinearLayout> 

該模塊被添加到線性佈局像這樣,setPayloadonBindViewHolder稱爲getItemViewType被稱爲後。

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 < 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 < 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(); 
    } 
} 

該模塊添加了線性佈局沒有問題。當我從模塊持有者LinearLayout撥打getChildAt並試圖將其投入RadioGroupModule時,會發生此問題。當用戶點擊LinearLayout中的模塊時,模塊構造函數傳入一個用於回調的接口。

該回調傳回已選定的JSONObject。從那裏我需要遍歷所有結果的JSONArray,並將所選其他對象中的選定值設置爲false,並且如果先前選擇了ImageViews源,則將其更改爲未選中,這是出現問題的位置。下面是我爲此寫的方法和複選框的JSONArray

public void setValuesAsFalse(JSONObject correctObject) throws Exception{ 
    JSONArray jsonArray = jsonObject.getJSONArray("values"); 
    for(int i = 0; i < 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); 
     } 
    } 
} 

和values數組。

[ 
    { 
    "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 
    } 
] 

該方法拋出以下ClassCastException

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) 

爲了討論我改變了這一行

RadioGroupModule radioGroupModule = (RadioGroupModule) ll_radio_group_holder.getChildAt(i); 

LinearLayout linearLayout = (LinearLayout) ll_radio_group_holder.getChildAt(i); 

和下面的例外是救援人員到場WN

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) 

使持有RadioGroupModuleLinearLayout沒有真正包含RadioGroupModule但他們無法施展調用getChildAt時。我希望RadioGroupModule處於這個位置的原因是,我可以撥打setSelected虛假,這將改變TextView背景顏色,並最終在獲得資產時更改ImageView源。

任何人都可以看到一個可能的解決方案嗎?還是不可能這樣做?

乾杯的任何幫助!

編輯:

我忘了把XML的RadioGroupModule的前端,這是低於此。

<?xml version="1.0" encoding="utf-8"?> 
<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"> 

    <ImageView 
     android:id="@+id/img_radio_group" 
     android:layout_width="60dp" 
     android:layout_height="60dp" /> 

    <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"/> 

</LinearLayout> 
+0

您可以發佈您的解決方案作爲答案並接受它,這樣這個問題被標記爲答案,而其他來這裏尋找類似問題的人會得到答案。 –

+0

只要你找到了你的問題的答案 - 然後發佈你的答案,而不是編輯你的問題,提供答案。 – azizbekian

回答

0

我修復了這個問題。問題在於,在調用getChildAt時,父佈局中同時存在RadioGroupModules和LinearLayouts,這導致了單獨的ClassCastExceptions。固定和工作循環看起來像這樣。

 for(int i = 0; i < ll_radio_group_holder.getChildCount(); i++){ 
      try{ 

       RadioGroupModule radioGroupModule = (RadioGroupModule) ll_radio_group_holder.getChildAt(i); 

       JSONObject jsonObject = radioGroupModule.getJsonObject(); 

       if(jsonObject.getInt("id") != correctObject.getInt("id")){ 
        radioGroupModule.setSelectedFalse(); 
        jsonObject.put("selected", false); 
       } else { 
        radioGroupModule.setSelectedTrue(); 
       } 

      } catch (Exception e){ 
       continue; 
      } 
     }