2013-08-07 53 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; 
} 

願這能幫助你。享受編碼。