0

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?

Nelmo
  • 195
  • 1
  • 3
  • 13

3 Answers3

0

public View getView (int position, View v, ViewGroup parent) is not invoking super.getView(position,v,parent) which is the one creating and binding the View instance. As you can see in CursorAdapter class:

 /**
 * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
 */
public View getView(int position, View convertView, ViewGroup parent) {
    if (!mDataValid) {
        throw new IllegalStateException("this should only be called when the cursor is valid");
    }
    if (!mCursor.moveToPosition(position)) {
        throw new IllegalStateException("couldn't move cursor to position " + position);
    }
    View v;
    if (convertView == null) {
        v = newView(mContext, mCursor, parent);
    } else {
        v = convertView;
    }
    bindView(v, mContext, mCursor);
    return v;
}
randomuser
  • 603
  • 4
  • 16
0

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

Community
  • 1
  • 1
mcd
  • 1,434
  • 15
  • 31
  • Doh!! - thank you very much, although I am now back to the semi-working version - but at least no crash. Thanks again... – Nelmo Jun 16 '14 at 14:22
0

I was having the same problem where the item click wasn't working, when using a custom adapter in a list view. I found the solution here: http://syedasaraahmed.wordpress.com/2012/10/03/android-onitemclicklistener-not-responding-clickable-rowitem-of-custom-listview/

Basically, you add this:

android:descendantFocusability="blocksDescendants"

to the parent view of your custom layout for a single item for the list(R.layout.trip_row) because the child views were blocking the event.

catorda
  • 479
  • 5
  • 11