Android ViewGroup删除子视图时应该注意的一个问题


在Activity中创建一个LinearLayout,创建一个scrollHorizon对象(scrollHorizon继承自ViewGroup),在scrollHorizon中调用createLayout函数来加载myView(继承自View)对象,然后调用deleteAllView函数来删除所有的视图。

scrollHorizon代码:

  1. public class scrollHorizon extends ViewGroup {  
  2.   
  3.     private Context context;  
  4.   
  5.     public scrollHorizon(Context context) {  
  6.         super(context);  
  7.           
  8.         this.context = context;  
  9.           
  10.         createLayout();  
  11.           
  12.         deleteAllView();  
  13.     }  
  14.     @Override  
  15.     protected void onLayout(boolean changed, int l, int t, int r, int b) {  
  16.           
  17.         int childCount = this.getChildCount();  
  18.         int childLeft = 0;  
  19.         int childTop = 0;  
  20.         for(int i = 0; i < childCount; i++){  
  21.             View child = getChildAt(i);  
  22.             child.setVisibility(View.VISIBLE);  
  23.             child.measure(r - l, b - t);  
  24.             child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(),childTop + child.getMeasuredHeight());  
  25.             if(childLeft <= 320){  
  26.                 childLeft = childLeft + child.getMeasuredWidth();  
  27.             }  
  28.             else{  
  29.                 childLeft = 0;  
  30.                 childTop = childTop + child.getMeasuredHeight();  
  31.             }  
  32.         }  
  33.     }  
  34.   
  35.     public void createLayout(){  
  36.       
  37.         Resources resource = this.getResources();  
  38.           
  39.         PackageManager pmanager = context.getPackageManager();  
  40.           
  41.         final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);  
  42.                 mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);  
  43.           
  44.                 List<ResolveInfo> list = pmanager.queryIntentActivities(mainIntent, 0);  
  45.           
  46.       
  47.                 forint i = 0; i < list.size(); i++){  
  48.                       int icon = R.drawable.contacts_button_normal;  
  49.                       LinearLayout linear = new LinearLayout(context);  
  50.                       linear.setLayoutParams(new LayoutParams(4545));  
  51.                       linear.setBackgroundDrawable(this.getResources().getDrawable(R.drawable.icon));  
  52.               
  53.                       ImageView image2 = new ImageView(context);  
  54.                       image2.setBackgroundDrawable(this.getResources().getDrawable(R.drawable.icon));  
  55.                       Drawable drawable = resource.getDrawable(icon);  
  56.               
  57.                       ImageView image = new ImageView(context);  
  58.               
  59.                       image.setBackgroundDrawable(drawable);  
  60.                       linear.addView(image2);  
  61.                       linear.addView(image);  
  62.                       this.addView(linear);  
  63.                }  
  64.     }  
  65.       
  66.     public void deleteAllView(){  
  67.         int size = this.getChildCount();  
  68.         forint i = 0; i < size; i++){  
  69.             this.removeViewAt(i);  
  70.         }  
  71.     }  
  72. }  
 
  1. myView代码:
  2. public class myView extends View {  
  3.   
  4.     public myView(Context context) {  
  5.         super(context);  
  6.           
  7.         setLayoutParams(new LayoutParams(40,40));  
  8.     }  
  9.   
  10. }  

主Activity代码:

  1. public class scrollHorizonTest extends Activity {  
  2.       
  3.      
  4.     public void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.           
  7.         LinearLayout linear = new LinearLayout(this);  
  8.           
  9.         scrollHorizon horizon = new scrollHorizon(this);  
  10.         
  11.         linear.addView(horizon);  
  12.            
  13.         this.setContentView(linear);  
  14.     }  
  15. }  

显示结果:



如果不调用deleteAllView函数,那程序没有问题,可以正常的进行显示,但调用deleteAllView函数存在空指针异常。

原因为:当你删除掉第一个View后(假设总共有两个View),当前ViewGroup的子视图只有一个,而这个子视图的位置变为0,所以当你调用removeViewAt(1)时会出现空指针异常,正确的删除方法应该是将deleteAllView函数中的removeViewAt(i)修改为removeViewAt(0);

相关内容