I have created a custom SimpleCursorAdapter in which i have overridden bindView
so I can connect an onClick
listener of an ImageButton in the list item layout. I want to start a new application on when the button is clicked using an Intent
with some extra data set from the underlying Cursor
.
The problem is that when the onClick
function of the button gets called, the cursor seems to no longer be pointing at the correct row in the database (I assume this is because it has been changed to point at a different row as the list scrolls).
Here is my code:
private class WaveFxCursorAdapter extends SimpleCursorAdapter {
public WaveFxCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
}
@Override
public void bindView(View v, Context context, Cursor c) {
super.bindView(v, context, c);
ImageButton b = (ImageButton) v.findViewById(R.id.btn_show_spec);
// fchr is correct here:
int fchr = c.getInt(c.getColumnIndex(
WaveDataContentProvider.SiteForecast.FORECAST_PERIOD));
Log.d(TAG, "ChrisB: bindView: FCHR is: " + fchr );
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(getActivity(), SpecDrawActivity.class);
i.setAction(Intent.ACTION_VIEW);
i.putExtra("com.kernowsoft.specdraw.SITENAME", mSitename);
// fchr is NOT CORRECT here! I can't use the fchr from the
// bindView method as Lint tells me this is an error:
int fchr = c.getInt(c.getColumnIndex(
WaveDataContentProvider.SiteForecast.FORECAST_PERIOD));
Log.d(TAG, "bindView: Forecast hour is: " + fchr);
i.putExtra("com.kernowsoft.specdraw.FCHR", fchr);
getActivity().startActivity(i);
}
});
}
As you can see from the comments in the code above, fchr
is correct when I print it to the log in bindView
but it is incorrect in the onClick
method. I tried referencing the fchr
variable in bindView
from the onClick
method, but Andriod Lint tells me i cant do this:
Cannot refer to a non-final variable fchr inside an inner class defined in a different method
My Question is: How can I correctly pass the fchr
variable from the cursor into the onClick
method?
Thanks!
The reason for the error is variable fchr
is a local variable in the bindView() method. The object that you create with the anonymous class might last until after the bindView() method returns.
When the bindView() method returns, local variables will be cleaned up from the stack, so they won't exist anymore after bindView() returns.
But the anonymous class object reference the variable fchr
. Things would go horribly wrong if the anonymous class object tries to access a variable after it have been cleaned up.
By making fchr
final, they are not really variables anymore, but constants. The compiler can then just replace the use of fchr
in the anonymous class with the values of the constants, and you won't have the problem with accessing non-existent variables anymore.