Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to override getView in a SimpleCursorAdapter gives NullPointerExceptio

Would very much appreciate any help or hint on were to go next.

I'm trying to change the content of a row in ListView programmatically. In one row there are 3 TextView and a ProgressBar. I want to animate the ProgressBar if the 'result' column of the current row is zero.

After reading some tutorials and docs, I came to the conclusion that LayoutInflater has to be used and getView() - overriden. Maybe I am wrong on this.

If I return row = inflater.inflate(R.layout.row, null); from the function, it gives NullPointerException.

Here is the code:

    private final class mySimpleCursorAdapter extends SimpleCursorAdapter {

    private Cursor localCursor;
    private Context localContext;

    public mySimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
        super(context, layout, c, from, to);            
        this.localCursor = c;
        this.localContext = context;

    }

    /**
     *    1. ListView asks adapter "give me a view" (getView) for each item of the list
     *    2. A new View is returned and displayed
     */
    public View getView(int position, View  convertView, ViewGroup  parent) {
        View row = super.getView(position, convertView, parent);

        LayoutInflater inflater = (LayoutInflater)localContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        String result = localCursor.getString(2);
        int resInt = Integer.parseInt(result);

        Log.d(TAG, "row " + row);

        // if 'result' column form the TABLE is 0, do something useful:
        if(resInt == 0) {           
            ProgressBar progress = (ProgressBar) row.findViewById(R.id.update_progress);
            progress.setIndeterminate(true);

            TextView edit1 = (TextView)row.findViewById(R.id.row_id);
            TextView edit2 = (TextView)row.findViewById(R.id.request);
            TextView edit3 = (TextView)row.findViewById(R.id.result);
            edit1.setText("1");
            edit2.setText("2");
            edit3.setText("3");
            row = inflater.inflate(R.layout.row, null);             
        }

        return row;
    }

here is the Stack Trace:

03-08 03:15:29.639: ERROR/AndroidRuntime(619): java.lang.NullPointerException
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:149)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.CursorAdapter.getView(CursorAdapter.java:186)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at com.dhristov.test1.test1$mySimpleCursorAdapter.getView(test1.java:105)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.AbsListView.obtainView(AbsListView.java:1256)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.ListView.makeAndAddView(ListView.java:1668)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.ListView.fillDown(ListView.java:637)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.ListView.fillSpecific(ListView.java:1224)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.ListView.layoutChildren(ListView.java:1499)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.AbsListView.onLayout(AbsListView.java:1113)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.view.View.layout(View.java:6830)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:998)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.LinearLayout.onLayout(LinearLayout.java:918)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.view.View.layout(View.java:6830)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:998)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.LinearLayout.onLayout(LinearLayout.java:918)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.view.View.layout(View.java:6830)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.view.View.layout(View.java:6830)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1119)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:998)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.LinearLayout.onLayout(LinearLayout.java:918)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.view.View.layout(View.java:6830)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.view.View.layout(View.java:6830)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.view.ViewRoot.performTraversals(ViewRoot.java:996)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.os.Looper.loop(Looper.java:123)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at android.app.ActivityThread.main(ActivityThread.java:4363)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at java.lang.reflect.Method.invokeNative(Native Method)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at java.lang.reflect.Method.invoke(Method.java:521)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
03-08 03:15:29.639: ERROR/AndroidRuntime(619):     at dalvik.system.NativeStart.main(Native Method)
like image 768
Dumitru Hristov Avatar asked Mar 08 '10 01:03

Dumitru Hristov


3 Answers

For CursorAdapter and subclasses, you should override newView() and bindView() instead of getView().

More importantly, though, you should not get calling super.getView(). That is where you are crashing.

like image 76
CommonsWare Avatar answered Nov 10 '22 01:11

CommonsWare


There is no need for getView() when extending the SimpleCursorAdapter class. All the functionality of getView() we get from the overriden newView() and bindView() methods.

if (convertview == null) // is equal to `newView()` and
if (convertview != null) // is equal to `bindView()`

One main difference is in getView(); we have the position as a parameter and in simpleCursorAdapter we get the position as getPositionForView(view) view is a parameter of bindView().

example: Mostly we are using Listview to put values...so you call ListViewObj.getPositionForView(view)

like image 29
jett Avatar answered Nov 10 '22 00:11

jett


Actually you should use a ViewBinder to achieve your custom binding. This way you do not have to override any code. Just make sure that you return true when you have set the value of the view otherwise the adapter will overwrite the value.

public void refresh() {
    Cursor cursor = ....get cursor....
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, 
            R.layout.list_item, 
            cursor, 
            new String[] { KEY_NAME, KEY_SHORT_DESC}, 
            new int[] { R.id.icon, R.id.text1});
    adapter.setViewBinder(new ProductViewBinder());
    setAdapter(adapter);
}

private static class ProductViewBinder implements ViewBinder {

    public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
        if (view instanceof ProgressBar) {
            String result = cursor.getString(2);
            Int resInt = Int.parseInt(result);

            if (resInt == 0) {
                ((ProgressBar)view).setIndeterminate(true);
                return true;
            }
        }

        return false;
    }
}
like image 29
Kjell-Åke Gafvelin Avatar answered Nov 10 '22 00:11

Kjell-Åke Gafvelin