问题:使用findviewById() 返回空,直到初始化控件的时候才报空指针异常。
今天写android自定义控件的时候突然发现了一个问题,也不报错,实在蛋疼。后面发现是因为自定义控件构造函数使用不对,
自定义构造函数有三个构造函数。
Class(Context); 普通构造函数,无法加载属性集(无法加载XML文件中定义的控件属性,导致无法从XML文件中
始 化)。
Class(Context,Attribute); 带属性集的构造函数,可以加载属性集(同时也可以加载XML文件中定义的属性)。
Class(Context,Attribute,int); 带属性集和默认风格的构造函数。
1、XML布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" android:orientation="vertical" > <ScrollView android:id="@+id/scrollView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/bg2" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <com.todayfocus.view.BannerFlipper android:id="@+id/banner_fliper" android:layout_width="match_parent" android:layout_height="150dp" > </com.todayfocus.view.BannerFlipper> <TextView android:layout_width="match_parent" android:layout_height="1dp" android:layout_marginTop="5dp" android:background="@android:color/darker_gray" android:text=" " /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:gravity="center" > <com.todayfocus.view.SubGridLayout android:id="@+id/grid_subscription" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="10dp" android:paddingRight="10dp" android:columnCount="3" > </com.todayfocus.view.SubGridLayout> </RelativeLayout> </LinearLayout> </ScrollView> </LinearLayout>
2、 代码:
public class BannerFlipper extends ViewFlipper implements DataSetObserver{ private Context mContext; private MyBaseAdapter mAdapter; private AttributeSet mAttrs; private int mNum = 0; public BannerFlipper(Context context){ //问题就处在这里,该构造函数没有属性参数,无法加载XML控件的参数,因此无法初始化。 super(context); mContext = context; } @Override public void onChanged() { mNum = mAdapter.getCount(); update(); } public void setAdapter(MyBaseAdapter adapter){ mAdapter = adapter; mAdapter.registerObserver(this); } private void update(){ this.removeAllViews(); for (int i = 0; i < mNum; i++) { RelativeLayout item = (RelativeLayout) mAdapter.getView(i); this.addView(item); } } }
在初始化的时候:
protected void findViews() { mBannerFlipper = (BannerFlipper) mView.findViewById(R.id.banner_fliper);//该处返回空指针,之后初始化报空指针异常 mGridLayout = (SubGridLayout) mView.findViewById(R.id.grid_subscription); }
后面多次调试之后,才发现是因为控件的构造函数中没有参数,因此无法加载XML文件里面的属性用来初始化。
问题就在于,自定义控件如果要在XML里面加载,就需要构造函数中有AttributeSet参数用来加载XML属性。