Search code examples
androidlistviewcursoradapter

Issues with a ListView and a custom cursorAdapter


Going in circles here - apologies if the code below looks a mess but I keep changing it following old/new advice from here and nothing is working...

Just trying to populate a listView from a DB with a cursor adapter, which has to be custom because I want to access individual fields in each row.

At best, I have had the listView reading and displaying the data correctly but the onClick wasn't working (no response at all, no logcat error). I have read numerous threads and tried various attempts but can't get it working and, worse, I can't now get back to that first semi-working version.

So, what I have is this - main activity:

public OnItemClickListener mTripClickHandler;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Create/prepare database (code removed for clarity)

    //Display trips - first get any entries     
    tripCur = mpgDB.query(dbHistory.TABLE_NAME, TRIP_PROJ, whereClause, null, null, null, null);
    int tmpCnt = tripCur.getCount();

    if (tmpCnt > 0) {
        tripCur.moveToFirst();

        // build a listView adapter
        Log.i(LOGTAG,"About to create listView...");
        //tripList = (ListView) findViewById(android.R.id.list);
        tripList = getListView();
        Log.i(LOGTAG,"ListView created...");

        Log.i(LOGTAG,"About to create adapter...");
        tripAdapter = new tripListAdapter(this, tripCur);
        setListAdapter(tripAdapter);
        setContentView(R.layout.activity_trip_display);

        //tripList.setOnItemClickListener(mTripClickHandler);

        tripList.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                // Do something in response to the click
                // Enable other buttons
                togBtns(true);
}
        });

Custom adapter:

// custom list adaptor class
private class tripListAdapter extends CursorAdapter {

    //private final Cursor dataC;
    private final LayoutInflater vi;
    public View theView;

    public tripListAdapter(Context con, Cursor c) {
        // super constructor thingy
        super(con, c);
        //dataC = c;
        vi = LayoutInflater.from(con);

    }

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

        Log.i(LOGTAG,"In getView...");
        // Create a message handling object as an anonymous class.
        //mTripClickHandler = new OnItemClickListener() {

        Log.i(LOGTAG,"Leaving getView...");
        return v;
    }

    @Override
    public void bindView(View v, Context arg1, Cursor dataC) {
        Log.i(LOGTAG,"In bindView...");
        // get data from cursor
        TextView dateTV = (TextView) v.findViewById(R.id.dateFld);
        TextView distTV = (TextView) v.findViewById(R.id.distFld);
        TextView mpgTV = (TextView) v.findViewById(R.id.mpgFld);

        String tmpMPG = dataC.getString(dataC.getColumnIndexOrThrow(dbHistory.TRIP_MPG));
        Double tmpNum = Double.valueOf(tmpMPG);
        tmpMPG = String.format("%.2f", tmpNum);

        dateTV.setText(dataC.getString(dataC.getColumnIndexOrThrow(dbHistory.TRIP_DATE)));
        distTV.setText(dataC.getString(dataC.getColumnIndexOrThrow(dbHistory.TRIP_MILES)));
        mpgTV.setText(tmpMPG);                      

        Log.i(LOGTAG,"Leaving bindView...");
    }

    @Override
    public View newView(Context arg0, Cursor arg1, ViewGroup arg2) {
        // TODO Auto-generated method stub
        Log.i(LOGTAG,"In newView...");
        theView = vi.inflate(R.layout.trip_row, arg2, false);

        Log.i(LOGTAG,"Leaving newView...");
        return theView;
    }

...and LogCat (top few lines only - all lines relate to system code, not mine):

06-16 09:49:38.110: I/WIBBLE(1184): About to create listView...
06-16 09:49:38.150: I/WIBBLE(1184): ListView created...
06-16 09:49:38.150: I/WIBBLE(1184): About to create adapter...
06-16 09:49:38.240: I/WIBBLE(1184): OnResume with this many rows returned by cursor: 3
06-16 09:49:38.240: I/WIBBLE(1184): In the loop, so cursor is not null....
06-16 09:49:38.320: I/WIBBLE(1184): In getView...
06-16 09:49:38.320: I/WIBBLE(1184): Leaving getView...
06-16 09:49:38.330: D/AndroidRuntime(1184): Shutting down VM
06-16 09:49:38.330: W/dalvikvm(1184): threadid=1: thread exiting with uncaught exception (group=0x414c4700)
06-16 09:49:38.452: E/AndroidRuntime(1184): FATAL EXCEPTION: main
06-16 09:49:38.452: E/AndroidRuntime(1184): java.lang.NullPointerException
06-16 09:49:38.452: E/AndroidRuntime(1184):     at android.widget.AbsListView.obtainView(AbsListView.java:2179)
06-16 09:49:38.452: E/AndroidRuntime(1184):     at android.widget.ListView.measureHeightOfChildren(ListView.java:1247)
06-16 09:49:38.452: E/AndroidRuntime(1184):     at a ndroid.widget.ListView.onMeasure(ListView.java:1159)
06-16 09:49:38.452: E/AndroidRuntime(1184):     at     android.view.View.measure(View.java:15848)
06-16 09:49:38.452: E/AndroidRuntime(1184):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5008)
06-16 09:49:38.452: E/AndroidRuntime(1184):     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)

Any ideas?


Solution

  • you have not return view from getView() method. current you return null value .that's why you get null pointer exception call newview inside getView() and return appropriate view .

    for more info read below SO Question

    What bindView() and newView() do in CursorAdapter