2013-08-07 69 views
3

在我的android应用程序,我从API的加载图像。但在网格视图中加载图像后,滚动不平滑。我使用异步线程来获取图像,以便它不会阻止用户界面。滚动是不光滑的android网格视图

现在有任何建议来提高滚动的性能。

+0

你重复使用ViewHolder模式吗? –

+1

您可以添加代码(适用于您的适配器)(具体为getView()方法) – Selecsosi

+0

我也有过这个问题,我减少了我的图像的大小,并完美的工作 –

回答

2

将图像加载到单独的线程中肯定有帮助,但是在这里需要处理另一个重要的性能问题,那就是“查看可重用性”,一旦您在适配器中设置了图像,请确保您实际上正在重用在适配器的getView方法中提供的视图,并且每次调用该方法时都不会创建/膨胀新的Layout(GridElement),这通常是导致滚动在所有图像加载后变慢的原因,有几种可用模式解决这个问题,你应该阅读有关ViewHolder,是最常见的,易于使用模式这个问题...

希望这有助于...

问候

+0

现在,滚动很好,但图像正在改变位置向下滚动。我传递imageView对象来设置下载后的图像。我使用ViewHolder保存ImageView,但问题仍然存在 –

0

代码getView()方法 {{{

@Override 
     public View getView(final int position, View convertView, ViewGroup parent) { 
       final HashMap<String, String> song = songsList.get(position); 
       imageURL = song.get(VariablesList.TAG_ALBUM_IMAGE); 
       View v = null; 
       if (convertView != null) 
         v = convertView; 
       else 
         v = inflater.inflate(R.layout.gridlayout_item, parent, false); 
       final ImageView imageView = (ImageView) v.findViewById(R.id.icon_image); 
       final Thread startAlbum = new Thread() { 
         public void run() { 

           imageView.setImageBitmap(AlbumList 
               .LoadImagetoGridView(imageURL)); 

           synchronized (this) { 
             this.notifyAll(); 
           } 
         } 
       }; 

       synchronized (startAlbum) { 
         startAlbum.start(); 
         try { 
           startAlbum.wait(); 
         } catch (InterruptedException e) { 
           e.printStackTrace(); 
         } 
       } 
       imageView.setOnClickListener(new View.OnClickListener() { 
         // @Override 
         public void onClick(View v) { 
           albumUrl = new StringBuffer(resources.getString(R.string.songsListURL)); 
           String albumIndex = song.get("id"); 
           albumName = (song.get("name")); 
           imageURL = song.get(VariablesList.TAG_ALBUM_IMAGE); 
           SongsList albumList = new SongsList(imageURL, albumUrl, 
               albumName,albumIndex,resources); 
           Thread threadAlbumList = new Thread(albumList); 
           threadAlbumList.start(); 

           synchronized (albumList) { 
             try { 
               albumList.wait(); 
             } catch (InterruptedException e) { 
               e.printStackTrace(); 
             } 
           } 
           if (!NewMediaPlayer.mediaPlayer.isPlaying()) { 
             HashMap<String, String> playingSong = NewMediaPlayer.selectedSongs 
                 .get(0); 
             if (playingSong != null) { 
               String url = playingSong.get("songUrl"); 
               String songName = playingSong.get("songName"); 
               if (songName != null) 
                 { 
                 NewMediaPlayer.songTitleLabel.setText(albumName 
                     + " - " + songName); 
                 NewMediaPlayer.songTitle.setText(albumName+"-"+songName); 
                 } 
               NewMediaPlayer.playSong(url); 
             } 
           } 
         } 
       }); 

       TextView itemAlbumName = (TextView) v.findViewById(R.id.icon_text); 
       itemAlbumName.setText(song.get("name")); 
       itemAlbumName.setOnClickListener(new View.OnClickListener() { 
         public void onClick(View v) { 
           HashMap<String, String> song = songsList.get(position); 
           String songIndex = song.get("id"); 
           String albumName = (song.get("name")); 
           Intent in = new Intent(context, SongListActivity.class); 
           in.putExtra("albumIndex", songIndex); 
           in.putExtra("albumName", albumName); 
           in.putExtra("AlbumImage", song.get(VariablesList.TAG_ALBUM_IMAGE)); 
           context.startActivity(in); 
         } 
       }); 

       return v; 
     } 

}}} 
+0

在强制主UI线程等待时,在单独的线程中执行setImageBitmap有什么意义? –

+0

如何在UI上加载位图图像呢? –

+0

仅仅在一个单独的线程上执行它,几乎就是你在做什么,但是不需要等待,因为它实际上将它加载到主线程上,因为无论如何您都在等待它加载,所以最好的方法是让线程运行自己做,一旦完成,然后你设置图像,但是你必须使用处理程序,因为为了修改视图,你需要在主线程中执行的代码。现在,如果你正在从URL下载imgs看看这个抽象项目,它有一个完美的缓存图像机制,所以如果一个图像已经被下载,它只是从缓存中获得它... –

0

而不是采取努力使用通用图像装载机library.And它的表现还是不错的。 在onCreate方法 gridView.setAdapter(new ImageAdapter(this,ImagesArrayPath));

private static class ImageAdapter extends BaseAdapter { 
    private final String[] IMAGE_URLS ; 

    private LayoutInflater inflater; 

    private DisplayImageOptions options; 

    ImageAdapter(Context context,String source[]) { 
     inflater = LayoutInflater.from(context); 
     IMAGE_URLS=source; 

     options = new DisplayImageOptions.Builder() 
       .showImageOnLoading(R.mipmap.ico_place_holder) 
       .showImageForEmptyUri(R.drawable.ic_empty) 
       .showImageOnFail(R.drawable.ic_error) 
       .cacheInMemory(true) 
       .cacheOnDisk(true) 
       .considerExifParams(true) 
       .bitmapConfig(Bitmap.Config.RGB_565) 
       .build(); 
    } 



    @Override 
    public int getCount() { 
     return IMAGE_URLS.length; 
    } 

    @Override 
    public Object getItem(int position) { 
     return null; 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     final ViewHolder holder; 
     View view = convertView; 
     if (view == null) { 
      view = inflater.inflate(R.layout.item_grid_image, parent, false); 
      holder = new ViewHolder(); 
      assert view != null; 
      holder.imageView = (ImageView) view.findViewById(R.id.image); 
      holder.progressBar = (ProgressBar) view.findViewById(R.id.progress); 
      view.setTag(holder); 
     } else { 
      holder = (ViewHolder) view.getTag(); 
     } 

     ImageLoader.getInstance() 
       .displayImage(IMAGE_URLS[position], holder.imageView, options, new SimpleImageLoadingListener() { 
        @Override 
        public void onLoadingStarted(String imageUri, View view) { 
         holder.progressBar.setProgress(0); 
         holder.progressBar.setVisibility(View.VISIBLE); 
        } 

        @Override 
        public void onLoadingFailed(String imageUri, View view, FailReason failReason) { 
         holder.progressBar.setVisibility(View.GONE); 
        } 

        @Override 
        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { 
         holder.progressBar.setVisibility(View.GONE); 
        } 
       }, new ImageLoadingProgressListener() { 
        @Override 
        public void onProgressUpdate(String imageUri, View view, int current, int total) { 
         holder.progressBar.setProgress(Math.round(100.0f * current/total)); 
        } 
       }); 

     return view; 
    } 
} 

static class ViewHolder { 
    ImageView imageView; 
    ProgressBar progressBar; 
} 

愿这能帮助你。享受编码。