Kendi özel bağdaştırıcınızı oluştururken getView () yöntemi nasıl çalışır?


102

Sorularım:

  1. LayoutInflater'ın işlevi tam olarak nedir?
  2. Neden okuduğum tüm makaleler, convertview'in boş olup olmadığını kontrol ediyor? Boş olduğu zaman ne anlama geliyor ve olmadığı zaman ne anlama geliyor?
  3. Bu yöntemin kabul ettiği üst parametre nedir?

Yanıtlar:


115

1: LayoutInflaterDüzen XML dosyalarınızı alır ve içeriğinden farklı Görünüm nesneleri oluşturur.

2: Bağdaştırıcılar, Görünümleri yeniden kullanmak için oluşturulmuştur, bir Görünüm artık görünür olmayacak şekilde kaydırıldığında, görünen yeni Görünümlerden biri için kullanılabilir. Bu yeniden kullanılan Görünüm convertView. Bu boş ise, geri dönüştürülmüş Görünüm olmadığı ve yeni bir tane oluşturmamız gerektiği anlamına gelir, aksi takdirde yeni bir görünüm oluşturmaktan kaçınmak için onu kullanmalıyız.

3: Bu parent, uygun yerleşim parametreleri için görünümünüzü şişirebilmeniz için sağlanmıştır.

Bunların tümü, listenizde görünecek görünümü (veya bir bağdaştırıcı alan başka bir görünümü) etkili bir şekilde oluşturmak için kullanılabilir:

public View getView(int position, @Nullable View convertView, ViewGroup parent){
    if (convertView == null) {
        //We must create a View:
        convertView = inflater.inflate(R.layout.my_list_item, parent, false);
    }
    //Here we can do changes to the convertView, such as set a text on a TextView 
    //or an image on an ImageView.
    return convertView;
}

Kullanımına dikkat LayoutInflater, parentbunun için bir argüman olarak kullanılabilir ve nasıl convertViewyeniden kullanılır.


5
Convertview == null, tüm öğeleriniz aynı düzeni izlediğinde kullanışlıdır. Örneğin bir radyo veya işaretli düğmeyi kontrol etmeniz ve her öğeye göre düzeni değiştirmeniz gerektiğinde, yeniden şişirmeniz gerekir, aksi takdirde önbelleğe alınmış görünümü alır.
çöktü

Yeniden şişirmeye gerek yok. Getview'da switch veya if-else ladder yazmanız ve görünümleri kendi durumunuza göre şişirmeniz, public int getItemViewType (int position) ve public int getViewTypeCount () 'u geçersiz kılmanız yeterlidir. @sagits
Prashanth Debbadwar

İfadeler genellikle işe yarıyorsa, ancak radyo düğmelerini kullanırken, metinleri ve bu tür şeyleri önbelleğe alınmış görünümleri kullanırken sorun yaşadığımda, yığın taşmasıyla ilgili bu şeylerle ilgili bazı sorular var.
sagits

71

getView()Adaptör yöntem ait üreten öğenin görünüm için ise ListView, Gallery...

  1. LayoutInflater(normalde kök nesne, bir bir düzen xml tanımlamak Görünüm nesne almak için kullanılır LinearLayout, FrameLayoutya da RelativeLayout)

  2. convertViewgeri dönüşüm içindir. Diyelim ki bir seferde yalnızca 10 öğe görüntüleyebilen bir liste görünümünüz var ve şu anda öğe 1 -> öğe 10'u görüntülüyor. Bir öğe aşağı kaydırdığınızda, öğe 1 ekran dışında kalacak ve öğe 11 görüntülenecektir . Öğe 11 için Görünüm oluşturmak üzere getView () yöntemi çağrılacaktır ve convertViewburada öğe 1'in görünümü (artık gerekli değildir). Öyleyse bunun yerine öğe 11 için yeni bir View nesnesi oluşturun (bu maliyetlidir), neden yeniden kullanmayasınız convertView? => convertViewnull olup olmadığını kontrol ederiz , eğer boş yeni görünüm yaratırsa, yoksa yeniden kullanırız convertView.

  3. parentViewöğenin görünümünü içeren bir liste görünümü veya Galeri ve ... getView()üretir.

Not : Bu yöntemi doğrudan çağırmazsınız, sadece ana görünüme öğenin görünümünü nasıl oluşturacağını söylemek için uygulamanız gerekir.


2
ParentView için MÜKEMMEL açıklama, bundan daha iyi bir açıklama bulamıyorum, +1
Ahmed Adel Ismail

İnanılmaz açıklama!
gabi

harika açıklama +1
tpk

8

Liste görünümü ile ilgili bu videoya göz atabilirsiniz. Son yıllardan kalma Google IO ve hala aklımdaki liste görünümlerinde en iyi gözden geçirme.

http://www.youtube.com/watch?v=wDBM6wVEO70

  1. Düzeni (res / layout / klasörünüzdeki xml dosyaları) LinearLayout ve diğer görünümler gibi java Nesnelerine şişirir.

  2. Videoya bakın, yeni bir nesne oluşturmaktan ve listenizin kaydırılmasını yavaşlatmaktan kaçınmak için, temelde sizin tarafınızdan yeniden kullanılmayı bekleyen geri dönüştürülmüş bir görünüm olan dönüştürülmüş görünümün kullanımıyla ilgili sizi bilgilendirecek.

  3. Adaptörden liste görünümüne başvurmanıza izin verir.


5

LayoutInflater'ın işlevi tam olarak nedir?

XML kullanarak tasarım yaptığınızda, tüm UI öğeleriniz yalnızca etiketler ve parametrelerdir. Bu UI öğelerini (ör. TextView veya LinearLayout) kullanmadan önce, bu xml öğelerine karşılık gelen gerçek nesneleri oluşturmanız gerekir. Şişirici bunun için. Şişirici, gerçek nesneleri oluşturmak ve tüm parametreleri ayarlamak için bu etiketleri ve bunlara karşılık gelen parametreleri kullanır. Bundan sonra, findViewById () kullanarak UI öğesine bir başvuru alabilirsiniz.

Neden okuduğum tüm makaleler, convertview'in boş olup olmadığını kontrol ediyor? Boş olduğu zaman ne anlama geliyor ve olmadığı zaman ne anlama geliyor?

Bu ilginç bir tanesidir. Gördüğünüz gibi, listedeki bir öğe her çizildiğinde getView () çağrılır. Şimdi, nesnenin çizilebilmesi için yaratılması gerekiyor. Şimdi convertView temelde bir öğeyi çizmek için kullanılan son görünümdür. GetView () 'de önce xml'yi şişirirsiniz ve ardından listitem'in çeşitli UI öğelerini almak için findByViewID () kullanırsınız. (ConvertView == null) 'u kontrol ettiğimizde, yaptığımız şey, eğer bir view null ise (ilk öğe için) o zaman onu oluşturmaktır, aksi takdirde, eğer zaten varsa, yeniden kullanmak, tekrar şişirme sürecinden geçmeye gerek yoktur. . Çok daha verimli hale getirir.

Ayrıca getView () içinde bir ViewHolder kavramıyla karşılaşmış olmalısınız. Bu, listeyi daha verimli hale getirir. Yaptığımız şey bir görüntü sahibi oluşturmak ve şişirdikten sonra elde ettiğimiz tüm UI öğelerine referansı depolamaktır. Bu şekilde, çok sayıda findByViewId () 'yi çağırmaktan kaçınabilir ve çok zaman kazanabiliriz. Bu ViewHolder (convertView == null) koşulunda oluşturulur ve setTag () kullanılarak convertView'de saklanır. Else döngüsünde, getView () kullanarak onu geri alırız ve yeniden kullanırız.

Bu yöntemin kabul ettiği üst parametre nedir?

Üst öğe, getView () tarafından oluşturulan görünümünüzün sonunda eklendiği bir ViewGroup'dur. Şimdi sizin durumunuzda bu ListView olacaktır.

Bu yardımcı olur umarım :)


4
  1. Düzen şişirici, mevcut görünümünüze harici XML'i şişirir / ekler.

  2. getView (), kaydırıldığında dahil olmak üzere birçok kez çağrılır. Bu yüzden eğer görüntüsü zaten şişirilmişse, şişirme maliyetli bir süreç olduğu için bunu tekrar yapmak istemeyiz .. bu yüzden boş olup olmadığını kontrol edip sonra şişiriyoruz.

  3. Üst görünüm, Listenizin tek hücresidir ..


3
Ebeveyn görüşü burada yanlış açıklanmıştır. Bu ListView olacak ListItem değil
Varun Jain

2

LayoutInflaterListViewöğe veya parçanın içindeki XML'nin dinamik görünümlerini oluşturmak için kullanılır onCreateView.

ConvertViewtemelde şu anda görünümde olmayan görünümleri geri dönüştürmek için kullanılır. Kaydırılabilir bir cihazınız olduğunu varsayalım ListView. Aşağı veya yukarı kaydırırken,convertView kaydırıldığında, kaydırılan görünümü verir. Bu yeniden kullanım hafızadan tasarruf sağlar.

getView()Yöntemin üst parametresi , listView olan üst düzene bir başvuru verir. Kullanabileceğiniz ana XML'deki herhangi bir öğenin kimliğini almak istediğinizi varsayalım:

ViewParent nv = parent.getParent();

while (nv != null) {

    if (View.class.isInstance(nv)) {
        final View button = ((View) nv).findViewById(R.id.remove);
        if (button != null) {
            // FOUND IT!
            // do something, then break;
            button.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Log.d("Remove", "Remove clicked");

                    ((Button) button).setText("Hi");
                }
            });
        }
        break;
    }

 }

1

getView()yöntem yeni Viewveya ViewGroupher satır Listviewveya Spinner için oluşturun. Bunu Viewveya klasördeki ViewGroupbir Layout XMLdosyada tanımlayabilir res/layoutve referansını verebilirsiniz.Adapter Object sınıfına .

Bağdaştırıcıya geçirilen bir Dizide 4 öğeniz varsa. getView()yöntem 4 Adaper satırı için 4 Görünüm oluşturacaktır.

LayoutInflater sınıfı, XML kaynak düzeninden Görünüm Nesnesini oluşturan bir Method inflate () öğesine sahiptir.


0

GetView hakkında faydalı bilgileri Adapter.java dosyasındaki Adaptör arayüzünde de bulabilirsiniz. Diyor ki;

/**
 * Get a View that displays the data at the specified position in the data set. You can either
 * create a View manually or inflate it from an XML layout file. When the View is inflated, the
 * parent View (GridView, ListView...) will apply default layout parameters unless you use
 * {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)}
 * to specify a root view and to prevent attachment to the root.
 * 
 * @param position The position of the item within the adapter's data set of the item whose view
 *        we want.
 * @param convertView The old view to reuse, if possible. Note: You should check that this view
 *        is non-null and of an appropriate type before using. If it is not possible to convert
 *        this view to display the correct data, this method can create a new view.
 *        Heterogeneous lists can specify their number of view types, so that this View is
 *        always of the right type (see {@link #getViewTypeCount()} and
 *        {@link #getItemViewType(int)}).
 * @param parent The parent that this view will eventually be attached to
 * @return A View corresponding to the data at the specified position.
 */
View getView(int position, View convertView, ViewGroup parent);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.