2013-04-20 99 views
0

我创建了一个自定义的SimpleCursorAdapter,其中我已覆盖bindView,因此我可以在列表项布局中连接ImageButton的onClick侦听器。我想在使用Intent以及底层Cursor的一些额外数据集单击按钮时启动一个新应用程序。自定义SimpleCursorAdapter - onClickListener重载bindView问题

问题是,当按钮的onClick函数被调用时,游标似乎不再指向数据库中的正确行(我假设这是因为它已被更改为指向不同的行该列表滚动)。

这里是我的代码:

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); 
     } 
    }); 
} 

正如你可以从上面的代码中的注释看,fchr是正确的,当我把它打印到日志中bindView,但它是在onClick方法不正确。我试图从onClick方法引用fchr变量bindView,但Andriod的皮棉告诉我,我不能这样做:

不能引用非最终变量FCHR在不同的方法定义的内部类中

我的问题是:如何正确地将光标的fchr变量传递给onClick方法?

谢谢!

回答

3

错误的原因是变量fchr是bindView()方法中的局部变量。使用匿名类创建的对象可能会持续到bindView()方法返回之后。当bindView()方法返回时,局部变量将从堆栈中清除,所以在bindView()返回后它们将不再存在。

但是匿名类对象引用变量fchr。如果匿名类对象在清理后尝试访问变量,情况就会变得非常糟糕。

通过使fchr最终,它们不再是真正的变量,而是常数。然后,编译器可以将匿名类中的fchr替换为常量的值,并且不会再有访问不存在的变量的问题。

Working with inner classes

+0

如果我在声明变量类,我仍然得到相同的Lint错误。那么是否会使变量最终产生影响? – ccbunney 2013-04-20 09:07:27

+0

检查我编辑的答案。 – 2013-04-20 09:08:05

+0

对不起 - 我的第一条评论是不正确的。在类中声明变量不会产生lint错误,但它仍会返回错误的fchr。做出可变的最终作品,但这是实现此目的的推荐方法吗?谢谢! – ccbunney 2013-04-20 09:14:55

0

代替:

b.setOnClickListener(new OnClickListener() { 

使用:

b.setOnClickListener(new MyClickListener(fchr)); 

和类MyClickListener会是什么样子:

class MyClickListener implements OnClickListener { 
    int mFchr; 
    public MyClickListener(int fchr) { 
     mFchr = fchr; 
    } 
    @Override 
    public void onClick(View v) { 
     // here you can access mFchr 
    } 
} 
+0

这是一个好主意。我可以试试 - 谢谢。 – ccbunney 2013-04-20 15:11:50

+0

啊,这不起作用,因为OnClickListener是一个接口,它没有构造函数。 – ccbunney 2013-04-20 15:16:49

+0

确定你是对的,改为扩展到实现 – pskink 2013-04-20 15:25:27