Moises Jimenez
Moises Jimenez

Reputation: 1962

Custom ListView not populating

I've been dealing with this for a few weeks now. I've already seen all other related questions and it does not help. I'm trying to populate a custom ListView and can't for the life of me get it to work. I'll post all the relevant information hoping someone will notice my mistake.

Activity Layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                tools:context=".MainActivity"
                android:background="#000000">

    <ListView
    android:id="@+id/deviceListView"
    android:layout_width="400px"
    android:layout_height="fill_parent"
    android:textColor="#ffffff"
    android:layout_centerVertical="true"
    android:layout_alignParentLeft="true"/>
</LinearLayout>

Custom Row layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="horizontal"
              android:background="#000000">
    <TextView android:id="@+id/textId"
              android:textSize="50sp"
              android:text="ID"
              android:textColor="#FFFFFF"
              android:textStyle="bold"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"/>
    <LinearLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
            android:orientation="vertical">
    <TextView android:id="@+id/textTimestamp"
              android:textSize="16sp"
              android:text="Timestamp"
              android:textColor="#FFFFFF"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"/>
              android:layout_height="wrap_content"/>

    <TextView android:id="@+id/textCoordinates"
              android:textSize="16sp"
              android:text="Coordinates"
              android:textColor="#FFFFFF"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"/>

    <TextView android:id="@+id/textDistance"
              android:textSize="16sp"
              android:text="Distance"
              android:textColor="#FFFFFF"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"/>
    </LinearLayout>
</LinearLayout>

Adapter model:

public class DeviceList {
    public static ArrayList<Device> list;

    public static void loadModel(int quantity) {
        ArrayList<Device> listTmp = new ArrayList<Device>();
        for (int i = 0; i < quantity; i++) {
            listTmp.add(new Device(System.currentTimeMillis(), i, new float[]{0, 0}, System.currentTimeMillis() / (i + 1)));
        }
        list = listTmp;
    }

    public static Device GetById(int id){
        Device tmp = null;
        for(Device device : list){
            if (device.getID() == id){
                tmp = device;
            }
        }
        return tmp;
    }
}

Adapter:

public class DeviceArrayAdapter extends ArrayAdapter<Device> {
    private Context context;
    private int rowResourceId;
    private String[] ids;

    public DeviceArrayAdapter(Context context, int rowResourceId, String[] devices) {
        super(context, rowResourceId);
        this.context = context;
        this.ids = devices;
        this.rowResourceId = rowResourceId;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.device_row, parent, false);
        TextView idTextview = (TextView) rowView.findViewById(R.id.textId);
        TextView timeStampTextview = (TextView) rowView.findViewById(R.id.textTimestamp);
        TextView coordinatesTextview = (TextView) rowView.findViewById(R.id.textCoordinates);
        TextView distanceTextview = (TextView) rowView.findViewById(R.id.textDistance);
        int id = Integer.parseInt(ids[position]);
        timeStampTextview.setText(Long.toString(DeviceList.GetById(id).getTimestamp()));
        idTextview.setText(DeviceList.GetById(id).getID());
        coordinatesTextview.setText(DeviceList.GetById(id).getCoordinates()[0] + "," + DeviceList.GetById(id).getCoordinates()[1]);
        distanceTextview.setText(DeviceList.GetById(id).getDistance() + "");
        return rowView;
    }
}

And finally the Activity's onCreate method:

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        setContentView(R.layout.activity_main);

//        ArrayList<Device> list = createDummyDeviceList(5);
        DeviceList.loadModel(5);
        String[] ids = new String[DeviceList.list.size()];
        for (int i= 0; i < ids.length; i++){

            ids[i] = Integer.toString(i+1);
        }
        ListView listView = (ListView) findViewById(R.id.deviceListView);
        DeviceArrayAdapter adapter = new DeviceArrayAdapter(this, R.layout.device_row, ids);
        listView.setAdapter(adapter);
}

Note: I'm sorry to post like this but I'm desperate. I've already debugged it up to the last line and everything is loaded and there are no Exceptions. But it just won't populate.

[EDIT]

Together with the selected answer I also had different numbered arrays and ids. The ids I generated started from 1 and not 0.

Upvotes: 0

Views: 491

Answers (2)

akelix
akelix

Reputation: 410

Check sources of ArrayAdapter http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/widget/ArrayAdapter.java#ArrayAdapter.getCount%28%29

In your case you should override method getCount().

Upvotes: 0

Blackbelt
Blackbelt

Reputation: 157437

You never pass the dataset to the super class. Change

super(context, rowResourceId);

with

super(context, rowResourceId, devices);

this way the getCount of the ArrayAdapter, returns the devices length and the getView would be invoked. Also to avoid waste of memory and better performance, you should inflate the convertView only once.

Edit. The super is expecting an Array or ArrayList of Device objects. Instead your devices in a String array. Your choice should be consistent. You can either change

extends ArrayAdapter<Device>

with

extends ArrayAdapter<String>

or pass as paramter a Device[] as parameter to your custom Adapter. For instance

public DeviceArrayAdapter(Context context, int rowResourceId, Device[] devices) {

Upvotes: 2

Related Questions