2010-09-30 15 views
28

İşte ArrayAdapter'im.ArrayAdapter'imi ViewHolder kalıbını nasıl izleyebilirim?

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/List14.html

ama bunu nasıl emin değilim: Ben ViewHolder desen izleyerek bu daha verimli hale getirmek istiyoruz.

GÜNCELLEME: ViewHolder Desen ViewHolder temelde oluşturulduğu zaman bir görünümü ile ilişkilendirmek statik sınıf örneğidir

private class QuoteAdapter extends ArrayAdapter<Quote> { 

    private ArrayList<Quote> items; 
    // used to keep selected position in ListView 
    private int selectedPos = -1; // init value for not-selected 

    public QuoteAdapter(Context context, int textViewResourceId, ArrayList<Quote> items) { 
     super(context, textViewResourceId, items); 
     this.items = items; 
    } 

    public void setSelectedPosition(int pos) { 
     selectedPos = pos; 
     // inform the view of this change 
     notifyDataSetChanged(); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View v = convertView; 
     ViewHolder holder; // to reference the child views for later actions 

     if (v == null) { 
      LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(R.layout.mainrow, null); 

      // cache view fields into the holder 
      holder = new ViewHolder(); 
      holder.nameText = (TextView) v.findViewById(R.id.nameText); 
      holder.priceText = (TextView) v.findViewById(R.id.priceText); 
      holder.changeText = (TextView) v.findViewById(R.id.changeText); 

      // associate the holder with the view for later lookup 
      v.setTag(holder); 
     } 
     else { 
      // view already exists, get the holder instance from the view 
      holder = (ViewHolder)v.getTag(); 
     } 

     // change the row color based on selected state 
     if (selectedPos == position) { 
      v.setBackgroundResource(R.drawable.stocks_selected_gradient); 
      holder.nameText.setTextColor(Color.WHITE); 
      holder.priceText.setTextColor(Color.WHITE); 
      holder.changeText.setTextColor(Color.WHITE); 
     } else { 
      v.setBackgroundResource(R.drawable.stocks_gradient); 
      holder.nameText.setTextAppearance(getApplicationContext(), R.style.BlueText); 
      holder.priceText.setTextAppearance(getApplicationContext(), R.style.BlueText); 
      holder.changeText.setTextAppearance(getApplicationContext(), R.style.BlueText); 
     } 

     Quote q = items.get(position); 
     if (q != null) { 
      if (holder.nameText != null) { 
       holder.nameText.setText(q.getSymbol()); 
      } 
      if (holder.priceText != null) { 
       holder.priceText.setText(q.getLastTradePriceOnly()); 
      } 
      if (holder.changeText != null) { 
       try { 
        float floatedChange = Float.valueOf(q.getChange()); 
        if (floatedChange < 0) { 
         if (selectedPos != position) 
          holder.changeText.setTextAppearance(getApplicationContext(), R.style.RedText); // red 
        } else { 
         if (selectedPos != position) 
          holder.changeText.setTextAppearance(getApplicationContext(), R.style.GreenText); // green 
        } 
       } catch (NumberFormatException e) { 
        System.out.println("not a number"); 
       } catch (NullPointerException e) { 
        System.out.println("null number"); 
       } 
       holder.changeText.setText(q.getChange() + " (" + q.getPercentChange() + ")"); 
      } 
     } 
     return v; 
    } 
} 
+0

XML Düzeni'nden ViewHolder kodu oluşturmak için çevrimiçi bir araç oluşturdum: http://www.buzzingandroid.com/tools/android-layout-finder/ – JesperB

cevap

44

, çocuğu önbelleğe çalışma zamanında yukarı aradığınız görüyor. Görünüm zaten mevcutsa, tutucu örneğini alın ve alanlarını findViewById numaralı telefonu aramak yerine kullanın. Senin durumunda

:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    ViewHolder holder; // to reference the child views for later actions 

    if (v == null) { 
     LayoutInflater vi = 
      (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.mainrow, null); 
     // cache view fields into the holder 
     holder = new ViewHolder(); 
     holder.nameText = (TextView) v.findViewById(R.id.nameText); 
     holder.priceText = (TextView) v.findViewById(R.id.priceText); 
     holder.changeText = (TextView) v.findViewById(R.id.changeText); 
     // associate the holder with the view for later lookup 
     v.setTag(holder); 
    } 
    else { 
     // view already exists, get the holder instance from the view 
     holder = (ViewHolder) v.getTag(); 
    } 
    // no local variables with findViewById here 

    // use holder.nameText where you were 
    // using the local variable nameText before 

    return v; 
} 

// somewhere else in your class definition 
static class ViewHolder { 
    TextView nameText; 
    TextView priceText; 
    TextView changeText; 
} 

uyarı: Bu derlemeye deneyin, böylece inanmayarak ile almadı.

+0

Bu tür bir soruyu daha önce sorduğum bir soru ile yapmak zorunda geri dönüşüm görünümleri. Görünüm oluşturmada yapılan performans analizlerini biliyor musunuz? – Falmarri

+0

@Falmarri Özel olarak değil, hayır. Bu özel model, View oluşturmadan ziyade findViewById'nin verimsizliğinden kaçınmaktır. Bununla birlikte, kendi Yeniden görüntüleme yeniden oluşturmayla ilgili analizinizi yapmak için bir test vakası yapmak çok kolay olacaktır. XML mizanpajını tek başına ayrıştırmanın, garantinin yeniden kullanılması için yeterli bir neden olabileceğinden şüpheleniyorum. Görünüm çok basitse ve programatik bir düzen oluşturuyorsa, yaratımda yer alan genel gider hakkında hiçbir bilgiye sahip değilim. – codelark

+0

mükemmel örnek kod. Görünüm tutucu kalıbını uyguladım. V.setBackgroundResource() 'a bakın View View düzeniyle ilgili olarak doğru bir şekilde yapıyorum? –

İlgili konular