2009-08-24 7 views
11

Listview "pürüzsüzce" nasıl yüklenir? İmleçten liste görünümüne veri yüklüyorum, ancak Liste görünümüm gerçekten "pürüzsüz" göstermiyor. ListView'imde scollbar üzerinde yukarı ve aşağı sürüklediğimde veri değişiyor. Ve bazı öğeler listemde yinelenen ekrana benziyor. "Karmaşık bir ListView" yazdım (iki textview, bir imageview) Bu yüzden verileri görüntülemek için newView(), bindView() kullandım. Birisi bana yardım edebilir mi?Android

cevap

11

Size sahip olduğunuz böyle bir sorunu nasıl alacağınızı anlatacağım. Muhtemelen bu size yardımcı olacaktır. Gördüğünüz gibi

public View getView(int position, View contentView, ViewGroup arg2) 
    { 
     ViewHolder holder; 

     if (contentView == null) { 
      holder = new ViewHolder(); 
      contentView = inflater.inflate(R.layout.my_magic_list,null); 
      holder.label = (TextView) contentView.findViewById(R.id.label); 
      contentView.setTag(holder); 
     } else { 
      holder = (ViewHolder) contentView.getTag(); 
     } 

     holder.label.setText(getLabel()); 

     return contentView; 
    } 

, biz tutucu aldıktan sonra liste öğesi değeri:

Yani, liste adaptörü böyle kodu var.

Ama yukarıdaki if deyimine kodu taşırsanız:

holder.label.setText(getLabel()); 

yüzden sonra aşağıda gibi görünecektir:

if (contentView == null) { 
    holder = new ViewHolder(); 
    contentView = inflater.inflate(R.layout.my_magic_list,null); 
    holder.label = (TextView) contentView.findViewById(R.id.label); 
    holder.label.setText(getLabel()); 
    contentView.setTag(holder); 
} 

liste öğesi çoğaltma ile mevcut uygulama davranış olacaktır.

Muhtemelen yardımcı olacaktır.

+0

Bu ayrıca yardımcı olur. Teşekkürler – Dennie

7

ListView zor bir yaratıktır.

Önce ikinci sorunuz: ListView, convertView ile Görüntüleme'yi yeniden kullandığı için yinelenen öğeler görüyorsunuz, ancak dönüştürülen görünümün tüm yönlerini sıfırladığınızdan emin olmuyorsunuz. convertView!=null kod yolunun görünüm için tüm verileri doğru şekilde ayarladığından emin olun ve her şey düzgün şekilde çalışmalıdır.

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    final MyCustomView v = convertView!=null ? (MyCustomView)convertView : new MyCustomView(); 
    v.setMyData(listAdapter.get(position)); 
    return v; 
} 

kendi özel görünümünü kullanmıyorsanız, sadece new MyCustomView() çağrısını ile değiştirin:

Sen getView() yöntem özel görünümler kullanıyorsanız aşağıdaki gibi kabaca bakmak istersiniz http://code.google.com/events/io/sessions/TurboChargeUiAndroidFast.html

onun konuşması

ve im sırasına göre: inflater.inflate(R.layout.my_layout,null) ilk sorunun itibariyle

çağrısı, buradan ListView performansına Romain'in TechTalk izlemek isteyeceksiniz Kendi deneyimlerinden portance, Kullanım convertView

  • Eğer resim varsa

    • anında resimlerinizi ölçekli değil. Eğer liste görünümü görünümler karmaşıklığını azaltın findViewByIds bir demet() Her zaman
    • aramak zorunda kalmamak için bir ölçekli bitmap oluşturmak için Bitmap.createScaledBitmap kullanın ve görüşleriniz
    • kullanın ViewHolder içine koydu. Daha az alt görüntü, daha iyi. RelativeLayout, LinearLayout'dan çok daha iyi. Özel görünümler uyguluyorsanız kullanın.
  • +0

    Üzgünüz, ama verileri görüntülemek için newView(), bindView() kullanın. aynı problem mi? – Dennie

    +0

    Sanırım videoyla ilgili yararlı bir şeyler buluyorum, paylaştığınız için teşekkürler! – Dennie

    1

    Bu sorunla da karşı karşıyayım, ancak benim durumumda dış görüntüleri almak için iş parçacıkları kullandım. Mevcut yürütme iş parçacığının, yeniden kullanıldığında görüntüyü değiştirmemesi önemlidir!

    public View getView(int position, View vi, ViewGroup parent) { 
    ViewHolder holder; 
    String imageUrl = ...; 
    
    if (vi == null) { 
        vi = inflater.inflate(R.layout.tweet, null); 
        holder = new ViewHolder(); 
        holder.image = (ImageView) vi.findViewById(R.id.row_img); 
        ... 
        vi.setTag(holder); 
    } else { 
        holder = (ViewHolder) vi.getTag();  
    } 
    holder.image.setTag(imageUrl); 
    ... 
    DRAW_MANAGER.fetchDrawableOnThread(imageUrl, holder.image); 
    } 
    

    Sonra getiriliyor parçacığı üzerinde ben önemli çeki yapıyorum:

    final Handler handler = new Handler() { 
    @Override 
    public void handleMessage(Message message) { 
        // VERY IMPORTANT CHECK 
        if (urlString.equals(url)) 
         imageView.setImageDrawable((Drawable) message.obj); 
    }; 
    
    Thread thread = new Thread() { 
    
    @Override 
    public void run() { 
        Drawable drawable = fetchDrawable(urlString); 
        if (drawable != null) { 
         Message message = handler.obtainMessage(1, drawable); 
         handler.sendMessage(message); 
        } 
    }}; 
    thread.start(); 
    

    biri kendi bakış yeniden kullanılır ise (o here açıklanan gibi) aynı zamanda mevcut iş parçacığı iptal olabilir, ama buna karşı karar verdim çünkü daha sonra yeniden kullanmak için önbelleğimi doldurmak istiyorum.

    0

    Yanlış şekilde işlediyseniz, yeniden açma metnini birden çok satırda görebilirsiniz. Son zamanlarda bunun hakkında biraz blog yazdım - bkz. here. Bunun dışında ListView performance optimization'a göz atmak isteyebilirsiniz. Genel olarak yeniden kullanım nedeniyle ve bunu birkaç kez gördüm.

    1

    Yalnızca bir ipucu: ASLA öğenin düzeninin arka planını kullanmayın - bu, performansı büyük ölçüde yavaşlatır.