开发者

layout as listview header

I have a layout that contains two lists. Since you can't put lists in a ScrollView I am trying to use an ExpandableListView, with a custom SimpleExpandableListAdapter, as per this question.

List layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent">
    <ExpandableListView android:id="@+id/android:list"
        android:layout_width="fill_parent" android:layout_height="fill_parent" />
</LinearLayout>

Now, the troubles come when I try to add something as header. It works if I create a layout from code, like this:

LinearLayout ll = new LinearLayout( this );
ll.setOrientation( LinearLayout.VERTICAL );
TextView t = new TextView( this );
t.setText( "some text" );
ll.addView( t );
ImageView i = new ImageView( this );
i.setImageResource( R.drawable.icon );
ll.addView( i );
getExpandableListView( ).addHeaderView( ll );

If I use the same layout, or simpler even than the one from code, the application crashes before even showing on screen. Here's the layout I want to add as header to the above list:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="wrap_content"
    android:orientation="vertical" android:id="@+id/ll">
        <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="some text"/>
        <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:src="@drawable/icon"/>
</LinearLayout>

And the code:

LinearLayout ll = (LinearLayout)findViewById( R.id.ll );
getExpandableListView( ).addHeaderView( ll );

I tried to fiddle with the layout_width or height of about all the components in my layout, but it doesn't work. What baffles me most is that when it crashes, on the DDMS says NullPointerException when calling setAdapter (which doesn't when I use the layout from code, and it adds the adapter just fine):

01-16 01:17:27.447: ERROR/AndroidRuntime(21314): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.stephan.test/org.stephan.test.ExpandableListViewTest}: java.lang.NullPointerException
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2833)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2854)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.app.ActivityThread.access$2300(ActivityThread.java:136)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2179)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.os.Looper.loop(Looper.java:143)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.app.ActivityThread.main(ActivityThread.java:5068)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at java.lang.reflect.Method.invokeNative(Native Method)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at java.lang.reflect.Method.invoke(Method.java:521)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at dalvik.system.NativeStart.main(Native Method)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314): Caused by: java.lang.NullPointerException
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.widget.ListView.clearRecycledState(ListView.java:506)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.widget.ListView.resetList(ListView.java:492)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.widget.ListView.setAdapter(ListView.java:424)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.widget.ExpandableListView.setAdapter(E开发者_如何学CxpandableListView.java:475)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.app.ExpandableListActivity.setListAdapter(ExpandableListActivity.java:246)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at org.stephan.test.ExpandableListViewTest.onCreate(ExpandableListViewTest.java:80)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1066)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2797)
01-16 01:17:27.447: ERROR/AndroidRuntime(21314):     ... 11 more

So, my question is: what am I doing wrong here? And, in case, any advices on how I could do this better?


I found the solution. Instead of creating a new layout with
LinearLayout ll = (LinearLayout)findViewById( R.id.ll );
you need to inflate it! The following does the trick:

LayoutInflater layoutInflater = (LayoutInflater)this.getSystemService( Context.LAYOUT_INFLATER_SERVICE );  
LinearLayout ll = (LinearLayout)layoutInflater.inflate( R.layout.ll, null, false );
getExpandableListView( ).addHeaderView( ll );

Where ll.xml is the layout you intend to attach to the list as a header. Hope this helps someone else! :)


ExpandableListActivity has a default layout that consists of a single, full-screen, centered expandable list. However, if you desire, you can customize the screen layout by setting your own view layout with setContentView() in onCreate(). To do this, your own view MUST contain an ExpandableListView object with the id "@android:id/list" (or list if it's in code)

http://developer.android.com/reference/android/app/ExpandableListActivity.html

So, in your custom layout, change the id from ll to @android:id/list. Also, call setContentView with your custom layout file.

I didn't understand quite well what you intended to do but as soon as you explain it better, I might help you further. (The way I see it, it seems that you want to get the list view and then add that list view to its header... weird)

EDIT:

just try to use the following layout:

<?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="match_parent"
         android:paddingLeft="8dp"
         android:paddingRight="8dp">

    <LinearLayout 
        android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:orientation="vertical" android:id="@+id/ll">
            <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:text="some text"/>
            <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:src="@drawable/icon"/>
    </LinearLayout>

     <ListView android:id="@id/android:list"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:background="#00FF00"

               android:drawSelectorOnTop="false"/>

     <TextView android:id="@id/android:empty"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:background="#FF0000"
               android:text="No data"/>
 </LinearLayout>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜