0

全部,

我的 Android 应用程序遇到了非常奇怪的崩溃。这是代码:

@Override
public View getView(int position, View convert, ViewGroup parent)
{
    View row = convert;
    ImageView image = null;
    TextView name = null, price = null;
    if( row == null )
    {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate( resource, parent, false );
        image = (ImageView) row.findViewById( R.id.product_picture );
        name = (TextView) row.findViewById( R.id.product_name );
        price = (TextView) row.findViewById( R.id.product_price );
        row.setTag( products.get( position ) );
    }
    Product product = products.get( position );
    name.setText( product.getProduct_name() );
    image.setImageBitmap( product.getProduct_picture() );
    price.setText( String.valueOf( product.getProduct_price() ) );
    return row;
}

此列表视图有 3 行。前2个是可见的,没有问题。但是,当我尝试滚动以显示第三行时,程序会因“name.setText(...);”行上的 NULL 指针异常而崩溃

我在我的 HTC 手机上运行,​​而不是模拟器。

有没有人经历过这样的事情?你如何调试和修复它?或者它可能表明手机坏了?

谢谢你。

4

3 回答 3

3

Listview 在滚动时重用行视图,而不是创建新视图。因此,在滚动时,您的“convert”不会为空,并且您不会运行“name = (TextView) row.findViewById(R.id.product_name)”并且“name”将保留为空。因此,当您稍后尝试将文本设置为名称时,您将得到 NullReferenceException。

您应该始终通过 findViewById 初始化您的小部件对象。

更改您的代码,它应该可以正常工作:

@Override
public View getView(int position, View convert, ViewGroup parent)
{
    View row = convert;
    ImageView image = null;
    TextView name = null, price = null;
    if( row == null )
    {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate( resource, parent, false );
    }
    image = (ImageView) row.findViewById( R.id.product_picture );
    name = (TextView) row.findViewById( R.id.product_name );
    price = (TextView) row.findViewById( R.id.product_price );
    row.setTag( products.get( position ) );

    Product product = products.get( position );
    name.setText( product.getProduct_name() );
    image.setImageBitmap( product.getProduct_picture() );
    price.setText( String.valueOf( product.getProduct_price() ) );
    return row;
}
于 2013-06-19T20:01:51.967 回答
3

这很有意义。

首先你设置name为null。如果row为空,那么您创建一个新行并获取name等,这应该可以正常工作。

但是,如果row不为空(即何时convertView不为空),则name永远不会设置,因此当您到达时将为空name.setText( product.getProduct_name() );

于 2013-06-19T20:02:21.263 回答
1

改成:

if( row == null ){
    LayoutInflater inflater = ((Activity) context).getLayoutInflater();
    row = inflater.inflate( resource, parent, false );
}

image = (ImageView) row.findViewById( R.id.product_picture );
name = (TextView) row.findViewById( R.id.product_name );
price = (TextView) row.findViewById( R.id.product_price );
row.setTag( products.get( position ) );

进行此更改的原因是,如果您的行不为空,您仍然需要告诉您的变量它们指向什么对象才能使用它们,否则您只会在创建新行时设置变量。

于 2013-06-19T20:03:39.710 回答