3

I get the list of customer info from my (testing) database, and I want to display it. The customer is represented by the Customer class with name, info, and note members. Its toString method returns only the name. I have created the DemoDatabaseMainActivity that uses the simple_list_item_1 layout only, thus displaying only the name of a customer -- like this:

public class DemoDatabaseMainActivity extends ListActivity {

    private CustomerDataSource datasource;

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

        datasource = new CustomerDataSource(this);
        datasource.open();

        List<Customer> values = datasource.getAllCustomers();

        ArrayAdapter<Customer> adapter = new ArrayAdapter<Customer>(this,
                                   android.R.layout.simple_list_item_1, values);
        setListAdapter(adapter);
    }
...
}

It works just fine; however, I'd like to learn the next step...

I would like to modify the code so that I could use the android.R.layout.simple_list_item_2 where name would be at the first line, and the info + note at the second line? What should be implemented instead of the Customer.toString(), and what adapter or whatever should I use?

Update based on Patric's comment https://stackoverflow.com/a/16062742/1346705 -- with respect to that, I have hoped for the modified solution like that:

public class DemoDatabaseMainActivity extends ListActivity {

    private CustomerDataSource datasource;

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

        datasource = new CustomerDataSource(this);
        datasource.open();

        List<Customer> values = datasource.getAllCustomers();

        TwolineAdapter adapter = new TwolineAdapter(this, values);  // here the difference
        setListAdapter(adapter);
    }
...
}

So, I have added my TwolineAdapter class this way:

public class TwolineAdapter extends ArrayAdapter<Customer> {

    private List<Customer> objects;

    public TwolineAdapter(Context context, List<Customer> objects) {
        super(context, android.R.layout.simple_list_item_2, objects);
        this.objects = objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = super.getView(position, convertView, parent);
        TextView text1 = (TextView) view.findViewById(android.R.id.text1);
        TextView text2 = (TextView) view.findViewById(android.R.id.text2);

        text1.setText(objects.get(position).getName());
        text2.setText(objects.get(position).getInfo() 
                      + " (" + objects.get(position).getNote() + ")");
        return view;
    }
}

But it did not work (apparently because of some of my errors). Notice the simple_list_item_2 in the super constructor code call. When running, the code shows the error log message like:

E/ArrayAdapter(27961): You must supply a resource ID for a TextView

I would like to ask you where the problem is. Trying to find the reason, I have modified the TwolineAdapter to work the same way as the original with the simple_list_item_1

public class TwolineAdapter extends ArrayAdapter<Customer> {

    private List<Customer> objects;

    public TwolineAdapter(Context context, List<Customer> objects) {
        super(context, android.R.layout.simple_list_item_1, objects);
        this.objects = objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView view  = (TextView)super.getView(position, convertView, parent);
        view.setText(objects.get(position).getInfo());  // displaying a different info
        return view;
    }
}

To be sure the overriden getView works, I have displayed a different part of the customer info. And it worked fine. In other words, instead of the general toString method, the result of my specific getInfo was displayed.

Anyway, I need to use the simple_list_item_2. What next should I do? (My conclusion is I am doing something wrong in the constructor. Am I right? Where is the problem?)

Community
  • 1
  • 1
pepr
  • 20,112
  • 15
  • 76
  • 139

2 Answers2

17

You can override the getView method of the ArrayAdapter:

  new ArrayAdapter (context, android.R.layout.simple_list_item_2, android.R.id.text1, list)
  {
    public View getView(int position, View convertView, ViewGroup parent) {
      View view = super.getView(position, convertView, parent);
      TextView text1 = (TextView) view.findViewById(android.R.id.text1);
      TextView text2 = (TextView) view.findViewById(android.R.id.text2);
      text1.setText("1");
      text2.setText("2");
      return view;
    }
  })
Patrick
  • 3,578
  • 5
  • 31
  • 53
  • I see. It is right in the `ArrayAdapter` doc (http://developer.android.com/reference/android/widget/ArrayAdapter.html). If I understand you well, I should create my own class that will extend the `ArrayAdapter`. Its `getView` will be the override that you suggest, right? – pepr Apr 17 '13 at 14:41
  • Thanks, Patric, for the hint. Please, have a look at the updated question. – pepr Apr 18 '13 at 08:38
2

Check out this tutorial on how to create a custom listView. Being a beginner it starts you from the new project stage, I think it would help you. As for what you should use instead of your toString() method, just create in your Customer class some getters to retrieve the data. Something like this:

public String getName(){
return this.name;
}

And use it in your code like this:

 Customer x = new Customer();
//return the customer name into a string, obviously you will return it in a list that you will pass it to the listview
String customerName = x.getName();
Cosmin Ionascu
  • 7,018
  • 5
  • 25
  • 42