2012-01-02 3 views
4

Я пытаюсь повторно использовать рамку, которая имеет изображение и текстовое изображение внутри него, но я не думаю, что я делаю это правильно. Код работает, и дисплей прав, но производительность очень плохая, и я считаю, что это связано с тем, что я создаю новый ImageView и TextView каждый раз, когда адаптеры возвращаются к позиции позиции.Android: повторное использование встроенных представлений в gridview [решение опубликовано]

Может ли кто-нибудь сказать мне, как повторно использовать встроенный ImageView (называемый i) и TextView (называемый t) без создания новых объектов? Я очень новичок в Java, и это моя попытка создать приложение для Android.

 public View getView(int position, View convertView, ViewGroup parent) { 

      FrameLayout F; 
      FrameLayout ImageBorder; 
      FrameLayout TextBG; 

      ImageView i; 
      TextView t; 

      if(convertView == null) { 
       F = new FrameLayout(mContext); 

      } else { 
       F = (FrameLayout) convertView; 
      } 

      ImageBorder = new FrameLayout(F.getContext()); 
      FrameLayout.LayoutParams params1 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,300,Gravity.BOTTOM); 
      ImageBorder.setLayoutParams(params1); 

      i = new ImageView(F.getContext()); 
      TextBG = new FrameLayout(F.getContext()); 
      t = new TextView(F.getContext()); 

      F.setBackgroundColor(Color.BLACK); 
      ImageBorder.setPadding(2, 2, 2, 2); 
      ImageBorder.setBackgroundColor(Color.BLACK); 

      FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,40,Gravity.BOTTOM); 

      TextBG.setLayoutParams(params); 
      TextBG.setBackgroundColor(Color.BLACK); 
      TextBG.setAlpha(.6f); 

      t.setLayoutParams(params); 

      t.setGravity(Gravity.CENTER_VERTICAL); 

      String pathToPhoto = FileList.get(position).toString(); 
      String fileDescription = pathToPhoto.replaceAll("/mnt/external1/PaliPhotography/",""); 

      fileDescription = fileDescription.replaceAll(".jpg",""); 
      fileDescription = fileDescription.toUpperCase(); 


      Bitmap bm = Cache.getCacheFile("thumb",pathToPhoto); 

      if (bm == null) { 
       ImageDownloader downloader = new ImageDownloader(i); 
       downloader.execute("thumb", pathToPhoto, "400", "400"); 
      } else { 

       i.setImageBitmap(bm); 
       i.setScaleType(ImageView.ScaleType.CENTER_CROP); 

       t.setTextAppearance(getApplicationContext(), android.R.style.TextAppearance_Large); 
       t.setText(" " + fileDescription); 

      } 

      ImageBorder.addView(i); 
      ImageBorder.addView(TextBG); 
      ImageBorder.addView(t); 

      F.addView(ImageBorder); 

      return F; 

     } 
    } 

Заранее спасибо!

[EDIT]

--------------------------- РЕШЕНИЕ -------- ---------------------------------------------

Вот решение, которое я реализовал на основе обратной связи ниже! Спасибо!

 public View getView(int position, View convertView, ViewGroup parent) { 

      View ReturnThisView; 
      ViewHolder holder; 

      LayoutInflater inflater; 
      holder = new ViewHolder(); 

      if(convertView == null) { 
       inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       ReturnThisView = inflater.inflate(R.layout.imagecell, null); 
       ReturnThisView.setTag(holder); 
      } else { 
       ReturnThisView = convertView; 
      } 

      holder.TextDescription = (TextView) ReturnThisView.findViewById(R.id.PhotoDesc); 
      holder.ImageThumbnail = (ImageView) ReturnThisView.findViewById(R.id.Thumbnail); 

      String pathToPhoto = FileList.get(position).toString(); 
      String fileDescription = pathToPhoto.replaceAll("/mnt/external1/PaliPhotography/",""); 

      fileDescription = fileDescription.replaceAll(".jpg",""); 
      fileDescription = fileDescription.toUpperCase(); 

      Bitmap bm = Cache.getCacheFile("thumb",pathToPhoto); 

      if (bm == null) { 
       ImageDownloader downloader = new ImageDownloader(holder.ImageThumbnail); 
       downloader.execute("thumb", pathToPhoto, "400", "400"); 
      } else { 

       holder.ImageThumbnail.setImageBitmap(bm); 
       holder.ImageThumbnail.setScaleType(ImageView.ScaleType.CENTER_CROP); 

       holder.TextDescription.setTextAppearance(getApplicationContext(), android.R.style.TextAppearance_Large); 
       holder.TextDescription.setText(" " + fileDescription); 

      } 

      return ReturnThisView; 
     } 
    } 

    static class ViewHolder { 
    TextView TextDescription; 
    ImageView ImageThumbnail; 
} 

ответ

2
  1. Вместо того, чтобы динамически создавать свой вид для каждого элемента создать файл макета XML, скажем row.xml.
  2. Если вы обнаружили, что convertView == null раздуть новую строку с помощью Inflater
  3. Найдите TextView и ImageView с помощью View # findViewById
  4. Создать объект Holder, который поможет держать ссылки на свой недавно найденной TextView и ImageView
  5. Сохранить держатель как тег так convertView.setTag(holder)
  6. для существующих convertView находят объект Holder, делая holder = convertView.getTag()
  7. Установить текст и изображение для этих двух сохраненных объектов, например, holder.txt.setText("Foo")
  8. Android адаптер будет делать все остальное, насколько повторное использование экземпляров завышенных рядов

Возможно даже для вашего кода вы можете сделать инициализацию вид и расположение раз и использовать держатель шаблона, чтобы избежать повторной инициализации элементов, но Я думаю, XML даст вам лучший опыт.

+0

Спасибо вам большое за помощь! У меня есть это решение наполовину реализовано уже, но я не знаю, что такое объект-держатель и как его реализовать. Является ли объект, который позволит мне удерживать как изображение, так и текст в себе? Я попытался найти объяснение и не смог найти хорошую информацию об использовании объектов Holder. – Apachi2K

+0

Ничего, нашел пример, который объяснил это! – Apachi2K

+1

Просто повторить. Держатель (или любое другое имя, которое вы решите дать) - это простой объект POJO (data), который содержит ссылки. В сложных ситуациях я обычно добавляю некоторое поведение к Holder, например, метод reset() – Bostone

0

Решение, которое вы предоставили, неточно. ViewHolder используется в основном для предотвращения раздувания представления и вызова findViewById() более одного раза.

В коде

  • Вы не должны создавать новый объект-держатель каждый раз! Вместо этого вы должны создать новый зритель только тогда, когда ваш convertView = null, а затем сохраните его в теге ReturnThisView. Если convertView не является нулевым, вы должны загрузить этот пользователь, который вы сохранили ранее.

  • Вы избегали раздувания зрения, так хорошо сделано (y), но вы все еще используете findViewById(). Используйте только findViewById(), когда convertView = null, и вы инициализируете представления в держателе вида. Если convertView не является нулевым, просто используйте сохраненные виды в объекте viewHolder, который вы загрузили.

Вот пример:

public View getView(int position, View convertView, ViewGroup parent) { 

     View ReturnThisView; 
     ViewHolder holder; 

     LayoutInflater inflater; 


     if(convertView == null) { 
      inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      ReturnThisView = inflater.inflate(R.layout.imagecell, null); 
      holder = new ViewHolder(); 
      holder.TextDescription = (TextView) ReturnThisView.findViewById(R.id.PhotoDesc); 
      holder.ImageThumbnail = (ImageView) ReturnThisView.findViewById(R.id.Thumbnail); 
      ReturnThisView.setTag(holder); 
     } else { 
      ReturnThisView = convertView; 
      holder = (ViewHolder)ReturnThisView.getTag(); 
     } 



     String pathToPhoto = FileList.get(position).toString(); 
     String fileDescription = pathToPhoto.replaceAll("/mnt/external1/PaliPhotography/",""); 

     fileDescription = fileDescription.replaceAll(".jpg",""); 
     fileDescription = fileDescription.toUpperCase(); 

     Bitmap bm = Cache.getCacheFile("thumb",pathToPhoto); 

     if (bm == null) { 
      ImageDownloader downloader = new ImageDownloader(holder.ImageThumbnail); 
      downloader.execute("thumb", pathToPhoto, "400", "400"); 
     } else { 

      holder.ImageThumbnail.setImageBitmap(bm); 
      holder.ImageThumbnail.setScaleType(ImageView.ScaleType.CENTER_CROP); 

      holder.TextDescription.setTextAppearance(getApplicationContext(), android.R.style.TextAppearance_Large); 
      holder.TextDescription.setText(" " + fileDescription); 

     } 

     return ReturnThisView; 
    } 
} 

static class ViewHolder { 
TextView TextDescription; 
ImageView ImageThumbnail; 

}

Я узнал его из этого site.

Смежные вопросы