Cannot add header view to list -- setAdapter has already been called.

来源:互联网 发布:ov7670中文数据手册 编辑:程序博客网 时间:2024/06/01 18:35
<span style="font-size:18px;">java.lang.IllegalStateException: Cannot add header view to list -- setAdapter has already been called.    at android.widget.ListView.addHeaderView(ListView.java:283)    at android.widget.ListView.addHeaderView(ListView.java:306)    at com.daojia.activitys.RestaurantActivity$1.onPostExecute(RestaurantActivity.java:372)    at com.daojia.activitys.RestaurantActivity$1.onPostExecute(RestaurantActivity.java:254)    at android.os.AsyncTask.finish(AsyncTask.java:417)    at android.os.AsyncTask.access$300(AsyncTask.java:127)    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)    at android.os.Handler.dispatchMessage(Handler.java:99)    at android.os.Looper.loop(Looper.java:138)    at android.app.ActivityThread.main(ActivityThread.java:3701)    at java.lang.reflect.Method.invokeNative(Native Method)    at java.lang.reflect.Method.invoke(Method.java:507)    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)    at dalvik.system.NativeStart.main(Native Method)</span>

       今天碰到了这样的一个问题,在4.3及以后以后没问题,只有在4.3之前版本上会出现问题。
提示我已经设置了适配器,原来在4.3之前版本上,手机上addHeaderView(View v)方法 只能在父控件 setAdapter之前调用!

       定位:Android版本问题,主要是因为在4.3之前,我们来看看Android4.3(API-18)和Android4.2(API-17)的Listview代码片段:

       在4.3中(api18)

public void addHeaderView(View v, Object data, boolean isSelectable) {  final FixedViewInfo info = new FixedViewInfo();  info.view = v;  info.data = data;  info.isSelectable = isSelectable;  mHeaderViewInfos.add(info);   // Wrap the adapter if it wasn't already wrapped.  if (mAdapter != null) {      if (!(mAdapter instanceof HeaderViewListAdapter)) {    mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);      }       // In the case of re-adding a header view, or adding one later on,      // we need to notify the observer.      if (mDataSetObserver != null) {    mDataSetObserver.onChanged();      }  }}
    在4.2中(api18)

<span style="font-size:18px;">public void addHeaderView(View v, Object data, boolean isSelectable) {   if (mAdapter != null && ! (mAdapter instanceof HeaderViewListAdapter)) {      throw new IllegalStateException(       <span style="color:#FF0000;"> "Cannot add header view to list -- setAdapter has already been called.");</span>  }   FixedViewInfo info = new FixedViewInfo();  info.view = v;  info.data = data;  info.isSelectable = isSelectable;  mHeaderViewInfos.add(info);   // in the case of re-adding a header view, or adding one later on,  // we need to notify the observer  if (mAdapter != null && mDataSetObserver != null) {      mDataSetObserver.onChanged();  }}</span>
     

API-17 中,假如 adapter不为空,则会直接抛出异常,而在API-18 中则做了相关的优化。

     建议 :

     木有建设性的提议,只能提醒大家,目前市面上主流的 Android系统还是Android4.3以下版本,所以在使用addHeaderView()要注意这一点。

     偶的解决方案:

     先添加AddHeaderView(),然后对Header做显示和隐藏处理。

    布局如下:

 <LinearLayout android:id="@+id/item_header"    android:layout_width="fill_parent"    android:layout_height="warp_parent"    android:orientation="vertical" >   <TextView  android:id="@+id/tv1" />   <TextView  android:id="@+id/tv2" /></LinearLayout 
  此时,有如下代码:
 <span style="font-size:18px;">ListView listView = xxxx; listView.addHearderView(item_</span>header<span style="font-size:18px;">); listView.setAdapter(adapter); adapter.add(xxxxx);<span style="font-family:Arial;">//</span>添加数据 item_root.setVisibility(View.GONE)</span>;

      最后一句应该可以起到隐藏headerView的目的,但实际效果,item_header的地方的确没有控件了,但item_root占有高度,和View.INVISIBILE效果一样了

      正确如下,修改itemView的结构:
 
<LinearLayout android:id="@+id/item_header"    android:layout_width="fill_parent"    android:layout_height="warp_parent"    android:orientation="vertical" >    <LinearLayout android:id="@+id/item_container"    <TextView  android:id="@+id/tv1" />    <TextView  android:id="@+id/tv2" />    </LinearLayout></LinearLayout >
这样就解决了问题 。

0 0
原创粉丝点击