2

I have a 2-column row layout that looks like this:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:paddingTop="4dip"
     android:paddingBottom="6dip"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal"
     android:textSize="13sp">

     <TextView android:id="@+id/TRAIN_CELL"
         android:layout_width="275dip"
         android:layout_height="wrap_content"/>

  <ImageView android:id="@+id/TO_CELL"
         android:layout_width="25dip"
         android:layout_height="wrap_content"  
         android:layout_weight="1"
         android:gravity="center"
         android:src="@drawable/arrow_button"/>

</LinearLayout>

And once I fetch items from the database, I display them in the left column, and in the right column I want to have a little image with an arrow signifying that it is a clickable item. But I am not sure how to make the image render. Here is how I currently populate that list:

I have these two variables:

private List<HashMap<String, String>> fillMaps;
private SimpleAdapter adapter;

At first I set them up like this:

list = (ListView) findViewById(android.R.id.list);

ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
//HashMap<String, String> map = new HashMap<String, String>();

// My data
fillMaps = new ArrayList<HashMap<String, String>>();

adapter = new SimpleAdapter(this, fillMaps, R.layout.questions_list,
        new String[] {"train", "to"}, 
        new int[] {R.id.TRAIN_CELL,  R.id.TO_CELL});
// This was the middle item R.id.FROM_CELL,

list.setAdapter(adapter);       
list.setTextFilterEnabled(true);

and when the data comes back from the server, I populate the list like this:

if ( obj != null )
                        {
                            questions.clear();

                            for ( int i = 0; i < obj.length(); i++ )
                            {
                                HashMap<String, String> map = new HashMap<String, String>();
                                JSONObject o = obj.getJSONObject(i);

                                question_id = o.getString("question_id");
                                question = o.getString("question");
                                question_by_member_id = o.getString("member_id");

                                Question q = new Question ( );
                                q.setQuestion( question );                      
                                q.setQuestionId( question_id );
                                q.setQuestionByMemberId(question_by_member_id);

                                map.put("train", question);

                                //map.put("from", ">");
                                //map.put("to", ">");

                                fillMaps.add(map);
                                questions.add( q );                             
                            }

                            adapter.notifyDataSetChanged();
                        }

But I am not getting the image to render. I think part of the problem is that I am using Strings as the data that the list expects, but I am not sure how to handle this with the images. The image is always the same image by the way.

Thanks!! :)

Genadinik
  • 18,153
  • 63
  • 185
  • 284

4 Answers4

2

Is this what you want?

<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:paddingTop="4dip"
     android:paddingBottom="6dip"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal"
     android:textSize="13sp">

     <TextView android:id="@+id/TRAIN_CELL"
         android:layout_width="275dip"
         android:layout_height="wrap_content"/>

     <ImageView android:id="@+id/TO_CELL"
         android:layout_width="25dip"
         android:layout_height="wrap_content"  
         android:layout_weight="1"
         android:gravity="center"
         android:src="@drawable/arrow_button"/>

</LinearLayout>

Addition
(Sorry, sometimes I miss notifications when they pile up over night. I believe you should be able to read messages / remove notifications here on Stack Overflow one by one or all at once, like an inbox...)

Anyway, if TO_CELL's image is always going to be the same, simply set the image in the XML only. Change your SimpleAdapter to this:

adapter = new SimpleAdapter(this, fillMaps, R.layout.questions_list,
        new String[] {"train"}, 
        new int[] {R.id.TRAIN_CELL});

Now your adapter only handles one string, you can simplify it to an ArrayAdapter (if you want.)


Simplified Example
You can also display one TextView and display a small "next" arrow like so:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:drawableRight="@android:drawable/ic_media_play"
    android:padding="10sp"
    android:textAppearance="?android:attr/textAppearanceMedium" />

(A LinearLayout and separate ImageView is not strictly necessary. I saved this as list_item.xml.) Here is a simple preview, understand that I left a lot of the non-critical lines out to not be repetitive:

public class Example extends Activity {
    ArrayAdapter<String> adapter;
    List<String> list = new ArrayList<String>();
    ListView listView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.text, list);
        listView = (ListView) findViewById(R.id.list);
        listView.setAdapter(adapter);

        updateList();
    }

    public void updateList() {
        ...
        if ( obj != null ) {
            questions.clear();
            list.clear();

            for ( int i = 0; i < obj.length(); i++ ) {
                JSONObject o = obj.getJSONObject(i);
                ...
                question = o.getString("question");
                list.add(question);
            }

            adapter.notifyDataSetChanged();
        }
    }
}

Hope this helps!

Sam
  • 86,580
  • 20
  • 181
  • 179
  • thank you, and do I have to change anything in how I set that image in the code? – Genadinik Sep 06 '12 at 20:19
  • I don't see where the image comes from in your code (a resource, a database), but this should help: [How do I set an ImageViews source programmatically in Android?](http://stackoverflow.com/q/5294031/1267661) – Sam Sep 06 '12 at 20:24
  • it is a resource. I get that I should probably do this: HashMap(); – Genadinik Sep 06 '12 at 20:26
  • Ok, if it is always the same resource then you do not have to change the image in your java code, setting it in the XML is enough. – Sam Sep 06 '12 at 20:27
  • I am trying this, but can't seem to get it right on the code side. I updated my code in the original question. Not sure where I am going wrong there. – Genadinik Sep 10 '12 at 15:27
  • Just like @Sam said, you should be able to set it in the layout. Otherwise it would look something like this: ... ImageView view = (ImageView) findViewById(R.id.TO_CELL); view.setImageResource(R.drawable.id_of_my_image); ... – bgs Sep 18 '12 at 04:38
2

I believe the easiest way is instead of using a SimpleAdapter try extending the ArrayAdapter for your needs. You can override the getView() method and populate your list the way you need!

There are a few examples here, here and here.

EDIT

First, you need a few modifications in your xml

<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:paddingTop="4dip"
 android:paddingBottom="6dip"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:orientation="horizontal"
 android:textSize="13sp">

     <TextView android:id="@+id/TRAIN_CELL"
     android:layout_width="275dip"
     android:layout_height="wrap_content"/>

 <ImageView android:id="@+id/TO_CELL"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:gravity="center"              
     android:background="#fff"/>
</LinearLayout>

In the following code I used a ArrayList of Strings for simplicity. You will have to replace that with a list of whatever object you are using to populate your list. (Question maybe?)

Create an ExtendedAdapter and override the getView() method to do what you intend. This will create a TextView and a ImageView on each row of the list, populate the TextView with the items in your ArrayList items and show the image if the item is clickable. (You have to do the verification by yourself but shouldn't be hard to figure it out)

public class ExtendedAdapter extends BaseAdapter {

public static final String TAG = "TodoAdapter";

private Context mContext;
private int layoutResource;
private boolean clickable = false;
private List<String> items; // you can replace this list with whathever you need
                            // for simplicity i'm assuming you already have the strings 
                            // you need for the textviews

public ExtendedAdapter(Context context, int textViewResourceId,
        List<String> items) {
    this.items = items;
    this.mContext = context;
    this.layoutResource = textViewResourceId;
}

public int getCount() {
    return items.size();
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(layoutResource, null);
    }

    ImageView arrow = (ImageView) v.findViewById(R.id.TO_CELL);
    TextView text = (TextView) v.findViewById(R.id.TRAIN_CELL);
    text.setText(items.get(position));
    if (clickable)  // here you have to do your check if it's clickable or not
        arrow.setBackgroundResource(R.drawable.ic_launcher);
    return v;
}
}

And in your activity, just set the list adapter

public class MainActivity extends Activity {

ListView yourList;
ArrayList<String> itemList = new ArrayList<String>();
ExtendedAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    yourList = (ListView) findViewById(R.id.yourList);



    adapter = new ExtendedAdapter(this, R.layout.row_layout, itemList);
    yourList.setAdapter(adapter);
    updateItems();
}

public void updateItems(){
    //dummy method, you should fetch your data and populate your array in a separate thread 
    //or something
    itemList.add("Text 1");
    itemList.add("Text 2");
    itemList.add("Text 3");
    itemList.add("Text 4");
    itemList.add("Text 5");
    itemList.add("Text 6");     
    adapter.notifyDataSetChanged();
}     


}

That's how you create a list with text and image.

Good luck!

caiocpricci2
  • 7,714
  • 10
  • 56
  • 88
  • This is indeed the way you should do it, just create a custom adapter +1 for gameower – Rolf ツ Sep 18 '12 at 15:52
  • And change your xml to this: it will center your image vertical: Add to your LinearLayout: android:gravity="center_vertical" – Rolf ツ Sep 18 '12 at 15:53
0

I think you should customize the list adapter and it will be easy this way.

Chandrashekhar
  • 498
  • 4
  • 19
0

The problem is with Layout and with the Simple adpater.

1.do not use linearLayout android:textSize="13sp" use it for TextView,

you can use below code

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:paddingBottom="6dip"
    android:paddingTop="4dip" >

    <TextView
        android:id="@+id/TRAIN_CELL"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight=".25"
        android:text="try out by yourself..."
        android:textSize="13sp" />

    <ImageView
        android:id="@+id/TO_CELL"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight=".05"
        android:gravity="center"
        android:src="@android:drawable/arrow_down_float" />

</LinearLayout>

2.The problem is in SimpleAdapter use

adapter = new SimpleAdapter(this, fillMaps, R.layout.questions_list, new String[] {"train"}, new int[] {R.id.TRAIN_CELL});

u.jegan
  • 833
  • 6
  • 15