2013-07-28 73 views
1

我使用從ArrayAdapter擴展的自定義適配器實現了我的ListView。 我的問題有時是ListView緩慢加載。這意味着一個空白活動首先加載沒有ListView,然後ListView出來。在最壞的情況下,我被提示「強行關閉或等待」。我喜歡改善緩慢加載,因爲這對用戶來說很煩人。如何提高ListView的加載時間?

但有時,加載速度很快,幾乎立即。

但我想確保我的ListView設計是正確的,並且設計沒有任何緩慢加載的問題。所以這個討論對於那些面臨和我一樣的問題的其他人是有用的。

我的ListView的設計如下。

每個ListItem有三個組件,縮略圖,ID文本和箭頭圖像,如圖所示image

ListView的加載過程中,(1)所有ID文本被從數據庫中檢索並填充到ListArray List<String> listIDs

 public class MyListFragment extends ListFragment implements OnItemClickListener { 
       dbHelper = new TrackerDBAdapter(getActivity()); 
       dbHelpLatLong = new LatLogDBAdapter(getActivity()); 
       dbHelpNotification = new NotificationDatabaseAdapter(getActivity()); 
       dbHelper.open(); 
       Cursor cursor = dbHelper.fetchAllTrackerInTheList(); 
       listIDs = new ArrayList<String>(); 
       activationStatus = new ArrayList<String>(); 
       thisListFragmentContext = getActivity(); 
       for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { 
        listIDs.add(cursor.getString(1));     
       } 
      dbHelper.close(); 

(2)Then my custom list adapter is called. 




     adapter = new customList_Adaptor(thisListFragmentContext, 
         R.layout.list_row, listIDs, this); 
     } 

That is the loading process inside my `ListFragment`. 

(3)下面的類是我的自定義ArrayAdapter和我實現加載縮略圖ImageView使用AsyncTask。我的查詢是

(i)我仍然從數據庫檢索ID文本,並加載箭頭圖像。我是否也應該將這些流程放入AsyncTask? (ii)如果我需要它,我應該執行另一個AsyncTask或使用相同的AsyncTask用於縮略圖圖像加載? (iii)其中,程序設計的哪個方面我仍然可以改進,對我的緩慢加載有疑慮?

public class customList_Adaptor extends ArrayAdapter<String>{ 


    protected static final int CAMERA_REQUEST = 0; 
    private TrackerDBAdapter dbHelper; 
    private Context context; 
    private List<String> listIDs = new ArrayList<String>(); 
    private List<String> activationState = new ArrayList<String>(); 
    public MyListFragment mMyListFragment; 
    public customList_Adaptor(Context context, int textViewResourceId, 
      List<String> objects, List<String> activationStatus, MyListFragment mMyListFragment) { 
     super(context, textViewResourceId, objects); 
     this.setContext(context); 
     this.listIDs = objects; 
     this.activationState = activationStatus; 
     this.mMyListFragment= mMyListFragment; 
     dbHelper = new TrackerDBAdapter(context); 
    } 


    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     if(listIDs != null) 
      return listIDs.size(); 
     else 
      return 0; 
    } 

    @Override 
    public String getItem(int arg0) { 
     // TODO Auto-generated method stub 
     if(listIDs != null) 
      return listIDs.get(arg0); 
     else 
      return null; 
    } 

    @Override 
    public long getItemId(int arg0) { 
     // TODO Auto-generated method stub 
     return arg0; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View vi=convertView; 
     ViewHolder viewHolder=new ViewHolder(); 
     LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     if(vi==null){ 
      vi = inflater.inflate(R.layout.list_row, parent, false); 
      viewHolder.id=(TextView)vi.findViewById(R.id.title); 
      viewHolder.thumbnailImage=(ImageView)vi.findViewById(R.id.list_image); 
      viewHolder.activationStatus = (TextView)vi.findViewById(R.id.activated); 
      //lazy load image 
      BitmapWorkerTask task = new BitmapWorkerTask(viewHolder.thumbnailImage); 
      task.execute(position); 

      viewHolder.arrow=(ImageView)vi.findViewById(R.id.list_arrow); 
      vi.setTag(viewHolder); 
     } 
     else 
      viewHolder=(ViewHolder) vi.getTag(); 

     viewHolder.thumbnailImage.setOnClickListener(new onMyClick(position));    
     // Setting all values in listview 
     viewHolder.id.setText(listIDs.get(position)); 

     if(activationState.get(position).equals("Not activated yet")){ 
      viewHolder.activationStatus.setText(activationState.get(position)); 
      viewHolder.activationStatus.setTextColor(android.graphics.Color.GRAY); 
     } 
     else if(activationState.get(position).equals("Activated")) 
      viewHolder.activationStatus.setText(""); 
     return vi; 
    } 

    public class onMyClick implements OnClickListener { 

     private final int pos; 
     public onMyClick(int pos) { 
      this.pos = pos; 
     } 

     @Override 
     public void onClick(View v) { 
      MyListFragment.clickedimageView = (ImageView) v.findViewById(R.id.list_image);      
      mMyListFragment.imagepos(pos); 
     } 

    } 

    public Context getContext() { 
     return context; 
    } 

    public void setContext(Context context) { 
     this.context = context; 
    } 

    //Lazy image update 
    class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> { 
     private final WeakReference<ImageView> imageViewReference; 
     private int data = 0; 

     public BitmapWorkerTask(ImageView imageView) { 
      // Use a WeakReference to ensure the ImageView can be garbage collected 
      imageViewReference = new WeakReference<ImageView>(imageView); 
     } 

     // Decode image in background. 
     @Override 
     protected Bitmap doInBackground(Integer... params) { 
      setData(params[0]); 
      Bitmap bitmap = null; 
      dbHelper.open(); 
      Cursor mCursor = dbHelper.getImagebyIDnumber(getData()); 
      byte[] img_bytes = mCursor.getBlob(13); 
      bitmap = BitmapFactory.decodeByteArray(img_bytes, 0, img_bytes.length);   

      dbHelper.close();   
      return bitmap; 
     } 

     // Once complete, see if ImageView is still around and set bitmap. 
     @Override 
     protected void onPostExecute(Bitmap bitmap) { 
      if (imageViewReference != null && bitmap != null) { 
       final ImageView imageView = imageViewReference.get(); 
       if (imageView != null) { 
        imageView.setImageBitmap(bitmap); 
       } 
      } 
     } 

     public int getData() { 
      return data; 
     } 

     public void setData(int data) { 
      this.data = data; 
     } 
    } 

    } 


public class ViewHolder { 
     TextView id; 
     TextView activationStatus; 
     ImageView thumbnailImage; 
     ImageView arrow; 
} 
+0

我使用數據庫來保存ListItem的所有內容。因此從數據庫中檢索數據是加載時的響應速度慢。所以我嘗試使用AsyncTask來檢索ListItem內容。但問題是,如果在調用自定義適配器時後臺進程仍在運行,則不會顯示ListView。 – batuman

回答

0

我做了一些事情,使其加載應用程序更快。 我不確定哪一個是解決方案。 (1)我使用AsyncTask加載了來自sql數據庫的所有數據,包括文本和縮略圖。 (2)我將縮略圖圖像格式從png更改爲jpg。 (3)然後手動清除緩存。 該應用在加載時看起來更快,但有時仍然很慢。大多數時候,它比以前更快。 我仍然在改進我的應用程序。 謝謝

+0

現在問題解決了,ListView可以非常快速地加載。現在我編寫了清除程序onDestroy()中的緩存。 – batuman

相關問題