应用程序的奇怪崩溃

时间:2013-06-19 19:58:41

标签: android view adapter

ALL,

我的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行。前两个是可见的,没有问题。但是,当我尝试滚动显示第3行时,程序崩溃,并在“name.setText(...);”行上出现NULL指针异常。

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

有没有人经历过这样的事情?你如何调试和修复它?或者它可能是电话坏了的指标?

谢谢。

3 个答案:

答案 0 :(得分:3)

Listview在滚动时重用行视图而不是创建新视图。因此,在滚动时,您的“转换”不会为null,您将不会运行“name =(TextView)row.findViewById(R.id.product_name)”,而“name”将保留为null。因此,当您稍后尝试将文本设置为名称时,您将获得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;
}

答案 1 :(得分:3)

这很有道理。

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

但是,如果row不为空(即当convertView不为空时),则永远不会设置name,因此当您到达{{1}时将为空}

答案 2 :(得分: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 ) );

此更改的原因是,如果您的行不为null,您仍然需要告诉您的变量在使用它们之前指向哪些对象,否则您只会在创建新行时设置变量。 / p>