Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set adapter in case of multiple textviews per listview?

I have a multiple TextViews per list item in my ListView. I've learned to write a proper getView method I believe but I'm not sure ho do I use setAdapter to call that method.

private static String[] project = {"proj1","proj2"};
private static String[] workRequests = {"requirement gathering", "design"};
private static String[] startDate = {"02/21/2012","07/15/2011"};
private static String[] status = {"WIP","DONE"};

ListView mListView;

public class MyDashboardActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mydashboard);

        final LayoutInflater mInflater = LayoutInflater.from(this);
        mListView = (ListView)findViewById(R.id.dashboardList);
        mListView.setAdapter(
                // How do I set the adapter?
                );
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        System.out.println("enters");
        if(convertView == null){
            convertView = LayoutInflater.from(this).inflate(R.layout.mydashboard,null);
        }

        ((TextView) convertView.findViewById(R.id.project)).setText(project[position]);
        ((TextView) convertView.findViewById(R.id.work_request)).setText(workRequests[position]);
        ((TextView) convertView.findViewById(R.id.start_date)).setText(startDate[position]);
        ((TextView) convertView.findViewById(R.id.status)).setText(status[position]);

        return convertView;
    }

This is the xml layout:

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

    <!-- Include Action Bar -->
    <include layout="@layout/actionbar_layout" />

    <ListView
        android:id="@+id/dashboardList"
        style="@style/LeftHeaderText"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:background="@drawable/innerdashboard_bg"
        android:textColor="@color/textColor" >

        <TextView android:id="@+id/project" />

        <TextView android:id="@+id/work_request" />

        <TextView android:id="@+id/start_date" />

        <TextView android:id="@+id/status" />

    </ListView>

</LinearLayout>

I've tried a few ways, none of which worked. Could anyone please suggest how to set the adapter in this case? Thanks!

like image 761
Harsh Avatar asked Jun 19 '12 17:06

Harsh


People also ask

How Array adapter is used to create views in a ListView?

Go to app > res > layout > right-click > New > Layout Resource File and create a new layout file and name this file as item_view. xml and make the root element as a LinearLayout. This will contain a TextView that is used to display the array objects as output.

What is the use of adapters in ListView & explain it with examples?

An adapter actually bridges between UI components and the data source that fill data into UI Component. Adapter holds the data and send the data to adapter view, the view can takes the data from adapter view and shows the data on different views like as spinner, list view, grid view etc.

What are adapters how it is different from list controls?

Adapter is an interface whose implementations provide data and control the display of that data. ListView s own adapters that completely control the ListView 's display. So adapters control the content displayed in the list as well as how to display it.


3 Answers

You need to implement your own Adapter. My way is to also define an object which "represents" a view.

Below, there is a very simple example with two TextViews to fit your needs.

The object which represents a view (a row in the ListView) :

public class CustomObject {

    private String prop1; 
    private String prop2;

    public CustomObject(String prop1, String prop2) {
        this.prop1 = prop1;
        this.prop2 = prop2;
    }

    public String getProp1() {
        return prop1;
    }

    public String getProp2() {
       return prop2;
    }
}

Next the custom adapter :

public class CustomAdapter extends BaseAdapter {

   private LayoutInflater inflater;
  private ArrayList<CustomObject> objects;

   private class ViewHolder {
      TextView textView1;
      TextView textView2;
   }

   public CustomAdapter(Context context, ArrayList<CustomObject> objects) {
      inflater = LayoutInflater.from(context);
      this.objects = objects;
   }

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

   public CustomObject getItem(int position) {
      return objects.get(position);
   }

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

   public View getView(int position, View convertView, ViewGroup parent) {
      ViewHolder holder = null;
      if(convertView == null) {
         holder = new ViewHolder();
         convertView = inflater.inflate(R.layout.your_view_layout, null);
         holder.textView1 = (TextView) convertView.findViewById(R.id.id_textView1);
        holder.textView2 = (TextView) convertView.findViewById(R.id.list_id_textView2);
         convertView.setTag(holder);
      } else {
         holder = (ViewHolder) convertView.getTag();
      }
      holder.textView1.setText(objects.get(position).getprop1());
      holder.textView2.setText(objects.get(position).getprop2());
      return convertView;
   }
}

Now you can define and set your adapter in your activity :

ArrayList<CustomObject> objects = new ArrayList<CustomObject>();
CustomAdapter customAdapter = new CustomAdapter(this, objects);
listView.setAdapter(customAdapter);

Now you only have to manage your CustomObject's in the objects list. Don't forget to invoke customAdapter.notifyDataSetChanged() when you want repercute modifications on the ListView.

like image 155
FabiF Avatar answered Nov 13 '22 13:11

FabiF


Your getView() code needs to go into a class that extends BaseAdapter or one of its subclasses.

One way to do this is to create a private class within your MyDashboardActivity. Here's a quick example below (some additional code will be required). You'll probably also want a custom object to associate all the things you want to display in one list item. Instead of multiple arrays, have one array of a custom type that has properties for each value you are tracking.

One more thing: your four TextViews should go into their own layout file (see list_item.xml here). That item layout file gets hooked up through the constructor of the custom adapter (I added a comment in the code below to highlight this).

protected CustomAdapter mAdapter;

public class MyDashboardActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mydashboard);

        final LayoutInflater mInflater = LayoutInflater.from(this);
        mListView = (ListView)findViewById(R.id.dashboardList);

        mAdapter = new CustomAdapter(this, <array to be adapted>);
        mListView.setAdapter(mAdapter);
    }

    private class CustomAdapter extends ArrayAdapter<String> {

        protected Context mContext;
        protected ArrayList<String> mItems;

        public CustomAdapter(Context context, ArrayList<String> items) {
            super(context, R.layout.custom_list_item, items); // Use a custom layout file
            mContext = context;
            mItems = items;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            System.out.println("enters");
            if(convertView == null){
                convertView = LayoutInflater.from(this).inflate(R.layout.mydashboard,null);
            }

            // You'll need to use the mItems array to populate these...
            ((TextView) convertView.findViewById(R.id.project)).setText(project[position]);
            ((TextView) convertView.findViewById(R.id.work_request)).setText(workRequests[position]);
            ((TextView) convertView.findViewById(R.id.start_date)).setText(startDate[position]);
            ((TextView) convertView.findViewById(R.id.status)).setText(status[position]);

            return convertView;
        }
    }
}
like image 39
Ben Jakuben Avatar answered Nov 13 '22 13:11

Ben Jakuben


There are a few ways to do this. I'll show you my way wich contains two layouts, the first being just the ListView its self and the other is how the text should appear per list item.

listset.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/shipMenu"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

listitems.xml (You can also put images in here, the idea here is control)

<?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="fill_parent"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/makerID"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:textSize="25dp"/>

</LinearLayout>

With the above I don't have the artwork yet but I intend to add an ImageView for icons (and you can add more TextViews too). Here is my custom adapter class.

ListAdapter.java

class ListAdapter extends ArrayAdapter <String>
{

    public ListAdapter(Context context, String[] values) {

        super(context, R.layout.listitems, values); //set the layout that contains your views (not the one with the ListView)
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater = LayoutInflater.from(getContext());
        View view = inflater.inflate(R.layout.listitems, parent, false); //same here.

        String text = getItem(position);

        TextView makerID = (TextView) view.findViewById(R.id.makerID);
        makerID.setText(text);

        return view;
    }

}

In your main activity file set

setContentView (R.layout.listset);

And add this underneath in same brackets as setContentView()

ListAdapter adapter = new ListAdapter(this, MyString[]); //place your String array in place of MyString

        ListView lv = (ListView) findViewById(R.id.ListViewID); //the ID you set your ListView to.
        lv.setAdapter(adapter);

Edit

I'm a bit late to the party it looks like but maybe this will help someone.

like image 40
c0dezer019 Avatar answered Nov 13 '22 15:11

c0dezer019