Android 巢狀佈局導致的Exception: java.lang.ClassCastException

yangxi_001發表於2014-07-20

RelativeLayout title_bg = (RelativeLayout)FTU_Bluetooth.this.findViewById(R.id.titlebar);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 0x55);
title_bg.setLayoutParams(params);

如果用RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(int, int),則會報Exception: java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams

這是因為在這裡的RelativeLayout在xml裡是套在LinearLayout裡的,必須建立父控制元件的LayoutParams。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/background" > <RelativeLayout android:id="@+id/titlebar" android:background="@drawable/main_title" android:layout_width="fill_parent" android:layout_height="66dp" >

--------------------------------------------------------------------------

下面轉帖壯志凌雲的部落格http://sunjilife.blog.51cto.com/3430901/1159639

在android中用程式碼動態新增元件或者改變某種佈局(元件)的高度時,會遇到如題所示的類轉換異常。

These supply parameters to the parent of this view specifying how it should be arranged. There are many subclasses of ViewGroup.LayoutParams, and these correspond to the different subclasses of ViewGroup that are responsible for arranging their children.

So basically, if you are adding a view to another, you MUST set the LayoutParams of the view to the LayoutParams type that the parent uses, or you will get a runtime error.

如果你要將一個view新增到另一個佈局中或者為這個view重新設定寬高等佈局屬性,你為該View設定的佈局引數型別與其父類所使用的佈局引數型別一樣。此外就是說若是最上層的佈局,則不需要設定此項。android中提供的佈局引數型別目前一共12種:ViewPager.LayoutParams,LinearLayout.LayoutParams,RelativeLayout.LayoutParams,TableLayout.LayoutParams等等。關於

LayoutParams的說明http://www.cnblogs.com/shaweng/archive/2012/07/10/2585134.html

 比如:

 

 

  1. <LinearLayout 
  2.   xmlns:android="http://schemas.android.com/apk/res/android"   
  3.   android:layout_width="wrap_content" 
  4.   android:layout_height="wrap_content">  
  5. <FrameLayout  
  6. android:id="@+id/FrameLayout01"  
  7. android:layout_width="wrap_content"  
  8. android:layout_height="wrap_content" /> 
  9. </LinearLayout> 
  10. 若想在程式碼中動態改變FrameLayout的大小,應該這樣寫: 
  11. FrameLayout frameLayout=(FrameLayout) convertView.findViewById(R.id.FrameLayout01);  
  12.  LinearLayout.LayoutParams ff=new LinearLayout.LayoutParams(LayoutParams.WRAP_C
  13. ONTENT, height); 
  14. frameLayout.setLayoutParams(ff); 

 

按照上面的說法,那麼若是底層佈局是LinearLayout,那麼新增view的時候指定的寬高引數就必然是Linear.Layout

Params,可我在嘗試過程中發現使用ViewGroup.LayoutParams,RelativeLayout.Params也可以執行,且不會出錯,以下是程式碼:

 

  1. //test.xml 佈局檔案 
  2.  
  3. <?xml version="1.0" encoding="utf-8"?> 
  4. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  5.     android:id="@+id/test_root_linearlayout" 
  6.     android:layout_width="fill_parent" 
  7.     android:layout_height="fill_parent" 
  8.     android:orientation="vertical" > 
  9.  
  10. </LinearLayout> 

 

  1. package com.example.aboutexpand; 
  2.  
  3. import android.app.Activity; 
  4. import android.os.Bundle; 
  5.  
  6. import android.view.ViewGroup; 
  7. import android.widget.LinearLayout; 
  8. import android.widget.RelativeLayout; 
  9. import android.widget.TextView; 
  10.  
  11. public class TestActivity extends Activity { 
  12.     @Override 
  13.     protected void onCreate(Bundle savedInstanceState) { 
  14.  
  15.         RelativeLayout rootLayout; 
  16.         super.onCreate(savedInstanceState); 
  17.         setContentView(R.layout.test); 
  18.         rootLayout = (LinearLayout) findViewById(R.id.test_root_linearlayout); 
  19.         LinearLayout.LayoutParams rootLinaerParams = new LinearLayout.LayoutParams( 
  20.                 100, 100); 
  21.         ViewGroup.LayoutParams rootGroupParams = new LinearLayout.LayoutParams( 
  22.                 100, 100); 
  23.         RelativeLayout.LayoutParams rootRelativeParams = new RelativeLayout.LayoutParams( 
  24.                 100, 100); 
  25.         TextView testView = new TextView(this); 
  26.         testView.setText("根佈局測試動態新增元件並設定其大小"); 
  27.         testView.setLayoutParams(rootGroupParams); 
  28.         rootLayout.addView(testView); 
  29.         // rootLayout.addView(testView, viewParams); 
  30. }

經過試驗,新增加的TextView的佈局引數使用LinearLayout.LayoutParams,RelativeLayout.LayoutParams,ViewGroup.LayoutParams都是可以正確顯示的,不相信的朋友,自己也可以試試看。至於這到底是什麼原因呢,我目前也不清楚,希望有知道的朋友留言指教一下,謝謝

相關文章