2013-06-19 2 views
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 전화기에서 실행 중입니다.

아무도 이런 경험이 없습니까? 어떻게 디버그하고 수정합니까? 아니면 전화가 나빠지는 것을 나타내는 지표일까요?

감사합니다.

답변

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; 
} 
+3

분명히 코드는 변경해야하지만 OP가 실수를 이해할 수 있도록 변경해야하는 이유/이유에 대해 자세히 설명 할 수 있습니까? – codeMagic

+0

물론. Listview는 새로운 뷰를 생성하는 대신 스크롤 할 때 행 뷰를 재사용합니다. 이 경우 "변환"은 null이 아니며 "name = (TextView) row.findViewById (R.id.product_name)"을 실행하지 않고 "name"은 null을 남깁니다. 그래서, 편지가 이름으로 텍스트를 설정하려고 할 때, 당신은 NullReference를 얻을 것입니다 – Dimmerg

+0

그게 더 낫지 만 설명으로 답을 업데이트하면 훨씬 도움이 될 것입니다. 그것은 단지 OP와 다른 사람들이 문제를 읽고 이해하는 것을 더 쉽게하며, 왜 이것이 문제를 해결 하는지를 이해하게합니다. 코드 답변 만 일반적으로 다음과 같이 나타납니다. ( – codeMagic

3

.

먼저 name을 null로 설정하십시오. row이 null이면 새 행을 만들고 name 등을 얻습니다. 그러면 정상적으로 작동합니다. row null가 아닌 경우 (convertView가 null가 아닌 경우 예)

그러나, 다음 name 설정되지 않습니다, 따라서 당신이 name.setText(product.getProduct_name());

+1

좋은 설명. 문제를 해결하려면 [Viewholder] (http://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder)를 사용하고 [Google I/O 터보가 UI를 충전하는 방법] (http : //www.google.com/events/io/2009/sessions/TurboChargeUiAndroidFast.html) 조금 오래되었지만 여전히 가치가있는 동영상 – codeMagic

1

변경에 도달하면 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)); 

이 변경의 이유는 행이 null이 아닌 경우 변수를 사용하기 전에 어떤 객체가 가리키는 객체인지를 변수에 알려줘야하기 때문입니다. 그렇지 않으면 새 행을 만들 때 변수 만 설정됩니다.

관련 문제