Android: повторное использование встроенных представлений в gridview [Решение опубликовано] - PullRequest
4 голосов
/ 03 января 2012

Я пытаюсь повторно использовать структуру кадра, в которой есть изображение и текстовое представление, но я не думаю, что делаю это правильно.Код работает, и отображение правильное, но производительность очень низкая, и я верю, что это потому, что я создаю новые ImageView и TextView каждый раз, когда адаптеры возвращаются в позицию элемента.повторно использовать встроенные 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 ]

2 голосов
/ 03 января 2012
  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 сделает все остальное до повторного использования экземпляров завышенных строк

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

0 голосов
/ 14 августа 2016

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

В вашем коде

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

  • Вы избежали раздувания представления, так что, молодец, но вы все еще используете 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;
* *} Тысяча двадцать-один

Я узнал об этом с этого сайта .

...