views:

938

answers:

2

Hi,

I have a LinearLayout defined in XML that I want to use repeatedly to display elements of a list. The XML-layout looks like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/background"
android:paddingBottom="5px"
>
<TextView  
android:id="@+id/destination"
android:layout_width="fill_parent" 
android:layout_height="wrap_content"
android:textSize="22dp"
android:text="@string/test_destination"
android:paddingLeft="5px"
/>

<TextView  
android:id="@+id/date"
android:layout_width="fill_parent" 
android:layout_height="wrap_content"
android:textSize="15dp"
android:text="@string/test_date"
android:paddingLeft="5px"
/>

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/info"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="5px"
android:paddingTop="10px" 
>
    <TableRow>
        <TextView
         android:id="@+id/reg_label"
         android:gravity="right"
         android:paddingRight="5px"
            android:text="@string/reg_label" />
        <TextView
            android:text="@string/test_registered"/>
    </TableRow>
    <TableRow>
        <TextView
         android:id="@+id/info_label"
         android:gravity="right"
         android:paddingRight="5px"
            android:text="@string/info_label" />
        <TextView
            android:text="@string/test_info"/>
    </TableRow>
</TableLayout> 
</LinearLayout>

I gather information about certain events from a webpage, and then I want to display all events in a list using the above layout for each event. My current approach is to have a LinearLayout as parent and then adding each event as a row.

Problem number one is to add the layout to each event (the number of events is varying). I.e., I want to dynamically inflate this layout for each event. I also don't want the text to be hard coded into the layout (as above) but added at runtime. I don't know how to do this. I have tried something like the following without any success.

LinearLayout eventView = (LinearLayout) findViewById(R.layout.event);
parentView.addView(eventView);

Problem number two is then to add these layouts to the parent view group and display it on the screen. When I try to do this using parent.addView(child), the program crashes at runtime and I can't figure out why.

It's kind of hard to describe the specific problem, since I'm new to GUI-programming on Android and I'm sort of programming by trial and error right now. Anyway, if you are able to help me with some of the problems it would be greatly appreciated.

Linus

EDIT:

Thanks commonsware, now the views inflate properly. The problem now is adding text dynamically to the TextViews. I try this:

TextView dest = (TextView) findViewById(R.id.destination);
dest.setText("myText");

only to discover that dest is null. Any ideas why and how to fix this?

EDIT 2:

I have narrowed the problem even more, but I really don't understand its nature. This is the trouble-method:

private void formatEvents(ArrayList<Event> events, LinearLayout parentView) {
    Log.d(TAG, "formatEvents, size: " + events.size());
    for (Event event : events) {

     LinearLayout eventView = new LinearLayout(this);
     eventView = (LinearLayout) getLayoutInflater().inflate(R.layout.event, null);
     parentView.addView(eventView);

     TextView dest = (TextView) findViewById(R.id.destination);
     TextView date = (TextView) findViewById(R.id.date);
     TextView registered = (TextView) findViewById(R.id.registered);
     TextView info = (TextView) findViewById(R.id.info);
     if (dest == null)
      Log.d(TAG, "null");
     else {
      Log.d(TAG, "not null");
      dest.setText(event.getDestination());
      date.setText(event.getDate());
      registered.setText(event.getDriver() + " " + event.getPassengers());
      info.setText(event.getInfo());
     }
    }  
}

I get null for the first iteration, but not for the second one. When I change

parentView.addView(eventView);

to

parentView.addView(eventView, 0);

it somehow works (even though the events are displayed in reverse order). Anyone knows what's going on here?

+1  A: 

On the whole, I would recommend you use a ListView rather than a LinearLayout as your container for your rows.

Problem number one is to add the layout to each event (the number of events is varying). I.e., I want to dynamically inflate this layout for each event.

parentView.addView(getLayoutInflater().inflate(R.layout.this_is_my_row));
CommonsWare
+1  A: 

Is id "destination" belongs to layout "event"?

If that is the case,

TextView dest = (TextView) findViewById(R.id.destination);
should be
TextView dest = (TextView) eventView.findViewById(R.id.destination);

bhatt4982
perfect, thanks!
aspartame