views:

1046

answers:

2
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="6dip">
    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_marginRight="6dip"
        android:src="@drawable/icon" />
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:layout_height="fill_parent">
        <TextView
            android:id="@+id/toptext"
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:textStyle="bold"
        />
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:id="@+id/bottomtext"
            android:singleLine="false"
        />
    </LinearLayout>
</LinearLayout>

This is my current row. If I created a .JPEG, and I want that to be for each item...how would I change this .xml file? Where would I put the image? In Assets?

A: 

Hi,

Did you want a list view where each row had its own background, like the one below?

alt text

In your code, you most likely would set a ListAdapter on the view. A number of the adapters that you can construct take in an layout or view argument. You should just have to set the android:background property for the view that you point this to.

For example, I might have an ArrayAdapter created like this:

new ArrayAdapter<String>(context, R.layout.item, R.id.itemName);

Of course, I use ListView's setAdapter with this adapter. In my item.xml file, I can define the text view itemName like this:

<TextView android:id="@+id/itemName" android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:text="Test view" android:background="@drawable/add"/>

However, I don't think all types of ListAdapter has a constructor with that feature. Check the documentation for the type of ListAdapter that you are using. If you are using one without this constructor, I think you may have to subclass the adapter and override the adapter's getView to inflate your view from your XML file.

I have the image add.png in each of res/drawable folders.

Klarth
A: 

If you want to have individual backgrounds for each list item, you must declare your own custom Adapter.

Derive it from BaseAdapter and the most important part to implement is the getView(int, View, ViewGroup) method.

You must understand how android re-uses already existing list item view elements when you scroll through a list. That means: at any moment in time, there will be only as many views generated as there can be seen on screen simultaneously.

This optimal strategy of not generating too many views altogether leads to the problem that you will have to set the background for each list item according to their position currenty needed when getView is called. If you would try to set the background statically only when generating the view, it will re-appear again possibly attached to the wrong element.

The getView method either brings a "convertView" as its second parameter or not (null). If your method is called with a convertView set to something, that means: "re-use this view for the item required right now".

The technique used here is nicely described within the API demos (section Lists) and there's also a video blog for that.

Here's how it might be done:

public class MyAdapter extends BaseAdapter {

    public View getView(int position, View convertView, ViewGroup parent) {
        // position is the element's id to use
        // convertView is either null -> create a new view for this element!
        //                or not null -> re-use this given view for element!
        // parent is the listview all the elements are in


        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.your_layout, null);

            // here you must do whatever is needed to populate the elements of your
            // list element layout
            ...
        } else {
            // re-use the given convert view

            // here you must set all the elements to the required values
        }

        // your drawable here for this element 
        convertView.setBackground( ... );

        // maybe here's more to do with the view
        return convertView;
    }
}

That's basically it. If there's only a few background drawings I would possibly cache them as well so you don't have to read the resources over and over again!

Have fun!

Zordid
How do you cache them?
TIMEX
Hold a list or array - whatever suites your needs - in your adapter and read in all drawables in the constructor of your Adapter. Then, when setting the background, instead of loading the resource there, use your list or array elements!But first: don't care about this. That was just an add-on hint from me to prevent your adapter being slow when flinging through your list!Good luck!
Zordid
How do I make that drawable repeat-x? In CSS, I can do repeat-x :)
TIMEX
Hmm, you mean repeat like tiles? I don't think that this is possible with the `setBackground` method of views. Views have one background image, that's it. But I might be wrong... :-)
Zordid