2011-07-27 58 views
0

目前我面臨以下問題出現 - 我創建一個自定義的ListView ( X ImageView的 + X 的TextView)。它顯示來自I-net的內容,這是一個XML文件。我怎麼能提高的ListView

我在做什麼 - 我使用的AsyncTask在後臺運行,下載XML內容和填補了的ListView的過程中,通過調用publishProgress(...)每個方法每個列表項從doInBackground(...)方法。當doInBackground(...)完成我已經收集到的URL每個和每一個形象我想從onPostExecute(...)顯示,然後方法我開始對下載過程圖像並更新每個下載的圖像的UI。對我而言,問題在於ListView應該至少填滿一些項目才能開始下載可繪製文件並更新列表。目前,列表視圖顯示單個項目,填充下一個項目時,所有圖像都已下載。我調試應用程序,我看到一個我停止在onPostExecute(...)方法,並希望採取ListView項目的數量,它只返回一個,因爲它顯示。

有沒有辦法強制出現列表視圖的項目,在開始下載之前,或者這是因爲I-net連接,我有足夠的內存,沒有延遲下載圖像。

我忘了只提到每個圖像都不大於10KB。

這是我的自定義的AsyncTask

private class DownloadFilesTask extends AsyncTask<String, Object, List<RSSItem>> { 
     protected void onPreExecute() { 
      super.onPreExecute(); 

      la.clear(); 
     } 
     protected List<RSSItem> doInBackground(String... urls) { 
      parse(urls[0]); 

      if (feed == null) { return null; } 

      rssList = feed.getAllItems(); 
      Iterator<RSSItem> iterator = rssList.iterator(); 

      while(iterator.hasNext()) { 
       if (isCancelled()) return null; 
       RSSItem rss = iterator.next(); 
       publishProgress(rss); 
      } 

      return rssList; 
     } 
     protected void onProgressUpdate(Object... progress) { 
      super.onProgressUpdate(progress); 

      la.add((RSSItem)progress[0]); 
      la.notifyDataSetChanged(); 
     } 
     protected void onPostExecute(List<RSSItem> result) { 
      super.onPostExecute(result); 

      Drawable downloadedImage; 
      for (int z = 0; z < rssList.size(); z++) { 
       downloadedImage = downloadImage(rssList.get(z).getImageURL()); 
       ((RSSItem)rssList.get(z)).setImage(downloadedImage); 
       la.notifyDataSetChanged(); 
      } 
     } 
     protected void onCancelled() { 
      super.onCancelled(); 
     } 
    } 

這裏是習俗Listadapter

private class ListAdapter extends ArrayAdapter<RSSItem> { 

     private List<RSSItem> items; 

     public ListAdapter(Context context, int textViewResourceId, List<RSSItem> items) { 
      super(context, textViewResourceId, items); 
      this.items = items; 
     } 

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

      if (v == null) { 
       LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       v = vi.inflate(R.layout.list_item, null); 
      } 

      RSSItem item = items.get(position); 

      if (item != null) { 
       ImageView itemImage = (ImageView) v.findViewById(R.id.ivImage); 
       TextView title = (TextView) v.findViewById(R.id.tvTitle); 
       TextView description = (TextView) v.findViewById(R.id.tvDescription); 
       if (item.getImage() != null) { 
        itemImage.setBackgroundDrawable(item.getImage()); 
       } else { 
        itemImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.icon)); 
       } 
       if (title != null) { 
        title.setText(item.getTitle()); 
       } 
       if (description != null) { 
        description.setText(item.getDescription()); 
       } 
      } 

      return v; 
     } 
    } 

...和項目類:

public class RSSItem { 
    private String data = null; 
    private String description = null; 
    private Drawable image = null; 
    private String imageUrl = null; 
    private String title = null; 

    RSSItem() { 
    } 

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

    public void setDescription(String description) { 
     this.description = description; 
    } 

    public void setImageURL(String imageURL) { 
     this.imageUrl = imageURL; 
    } 

    public void setImage(Drawable image) { 
     this.image = image; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public String getData() { 
     return data; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public Drawable getImage() { 
     return image; 
    } 

    public String getImageURL() { 
     return imageUrl; 
    } 

    public String getTitle() { 
     return title; 
    } 
} 

@MODIFICATIONS:

私有類DownloadFilesTask延伸的AsyncTask> { 保護無效onPreExecute(){ super.onPreExecute();

 la.clear(); 
    } 

    protected List<RSSItem> doInBackground(String... urls) { 
     parse(urls[0]); 

     if (feed == null) { return null; } 

     rssList = feed.getAllItems(); 
     publishProgress(true); 

     Drawable downloadedImage; 
     for (int z = 0; z < rssList.size(); z++) { 
      downloadedImage = downloadImage(rssList.get(z).getImageURL()); 
      ((RSSItem)rssList.get(z)).setImage(downloadedImage); 
     } 
     return rssList; 
    } 

    protected void onProgressUpdate(Object... progress) { 
     super.onProgressUpdate(progress); 

     la.notifyDataSetChanged(); 
    } 

    protected void onPostExecute(List<RSSItem> result) { 
     super.onPostExecute(result); 

     la.notifyDataSetChanged(); 
    } 

    protected void onCancelled() { 
     super.onCancelled(); 
    } 
} 

回答

2

我不知道我理解你的問題,但我會做的是以下內容(如果我這樣做是正確):

我想你,你在你的ListView存儲自定義對象,讓我們說定製項目。 我會將URL Image的下載放在該對象的構造函數中,並將Drawable作爲CustomItem的成員來存儲。剛剛創建了新的CustomItem並獲得了該圖像後,publishProgress()並在您的列表適配器上調用notifyDataSetChanged()

編輯:您應該從方法末尾的onPostExecute()方法移動代碼。

試試這個:

private class DownloadFilesTask extends AsyncTask<String, RSSItem, Void> { 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     la.clear(); 
    } 
    protected List<RSSItem> doInBackground(String... urls) { 
     parse(urls[0]); 

     if (feed == null) { return null; } 
     rssList = feed.getAllItems(); 
     Iterator<RSSItem> iterator = rssList.iterator(); 

     while(iterator.hasNext()) { 
      if (isCancelled()) return null; 
      RSSItem rss = iterator.next(); 
      //this happens fast no need to do this 
      publishProgress(rss); 
      //la.add(rss); 
     } 
     Drawable downloadedImage; 
     for (int z = 0; z < rssList.size(); z++) { 
      downloadedImage = downloadImage(rssList.get(z).getImageURL()); 
      ((RSSItem)rssList.get(z)).setImage(downloadedImage); 
      publishProgress(null); 
     } 
     return rssList; 
    } 
    protected void onProgressUpdate(RSSItem... progress) { 
     super.onProgressUpdate(progress); 
     if progress!=null 
      la.add((RSSItem)progress[0]); 
     la.notifyDataSetChanged(); 
    } 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 

    } 
    protected void onCancelled() { 
     super.onCancelled(); 
    } 
} 
+0

好的,你誤解我想做的事情。首先,我已經知道你在說這個,它正在工作,但我不想下載一個圖像並將其填充到** ListView **中。我只想填充文本,並且會顯示一個默認的靜態圖像,而不是原始的靜態圖像。在** doInBackground **完成後,它返回一個值給** onPostExecute **,在那裏我將執行所有圖像的下載。您可以通過我分享的來源查看以上內容。 – nenito

+0

好的。我現在明白了。 doBackground中的代碼將很快完成,問題是您在'postExecute()'中執行耗時的代碼部分,它將在UIThread上運行,並會阻止您的用戶界面。檢查我編輯的答案。 –

+0

您的意思是在'return'語句之前將兩行代碼從** onProgressUpdate(...)**移動到** doInBackground(...)**。如果是這樣,它會產生一個異常。我也不確定我可以從** doInBackground(...)**調用** notifyDataSetChanged(...)**,它們分別運行在兩個不同的威脅** doInBackground(...)* * - 關於UI威脅的Backgroud威脅和** notifyDataSetChanged(...)** – nenito

1

您是否正在填充列表適配器的基礎數據集doInBackground()?然後,除了致電publishProgress()之外,您還需要致電AsyncTaskonProgressUpdate()中的adapter.notifyDataSetChanged()

+0

是的,這正是我在做什麼,現在!也許我應該發佈一些代碼... – nenito