2013-08-27 64 views
1

如何設置這種佈局的圖像?Android:如何在此ListView中設置圖像?

List Entry

的ListView的將含有上述項3中,各圖像將被在一個AsyncTask(見下文)下載和文本將通過預設字符串字符串數組被填充在例如

String[] values = {"string one", "string two", "String three"}; 

我希望能夠使用下面的適配器首先設置所有3個條目的字符串內容值,然後在後臺下載並運行AsyncTasks,併爲每個條目設置圖標。

字符串比圖標更重要,所以我不希望用戶必須等待每個圖標才能在字符串設置之前下載。

我有一個ListView佈局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal" 
    android:paddingBottom="@dimen/small_8dp" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/small_8dp" > 

    <ImageView 
     android:id="@+id/logo" 
     android:layout_width="50dp" 
     android:layout_height="50dp" 
     android:contentDescription="@string/loading" 
     android:scaleType="fitXY" 
     android:src="@drawable/image" > 

    </ImageView> 

    <TextView 
     android:id="@+id/label" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:paddingLeft="@dimen/small_8dp" 
     android:text="@string/loading" 
     android:textSize="@dimen/medium_15dp" > 

    </TextView> 

</LinearLayout> 

這是一個佈局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@color/color_white" 
    android:orientation="vertical" > 

    <ListView 
     android:id="@android:id/list" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:entries="@array/list_headlines"> 
    </ListView> 

</LinearLayout> 

香港專業教育學院一直與這個自定義適配器:

private class ArticleAdapter extends ArrayAdapter<String>{ 
     private final Context context; 
     private final String[] values; 

     public ArticleAdapter(Context context, String[] values) { 
      super(context, R.layout.list_entry, values); 
      this.context=context; 
      this.values=values; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      View rowView = inflater.inflate(R.layout.list_entry,parent,false); 
      TextView tv = (TextView) rowView.findViewById(R.id.label); 

      tv.setText(values[position]); 

      return rowView; 
     } 
    } 

LoadThumbnail的AsyncTask:

protected class LoadThumbnail extends AsyncTask<String, Void, String> { 
     private String url; 
     private boolean loaded; //if loaded set the bitmap image to whats downloaded 
     private Bitmap icon; 
     private int iconIndex; 

     public LoadThumbnail(int iconIndex, String url){ 
      loaded = false; 
      this.url = url; //url of the icon to download 
      this.iconIndex=iconIndex; //Which icon in the listview were downloading 
     } 

     @Override 
     protected String doInBackground(String... params) { 
      Download download = new Download(url); //My Download Class 
      try { 
       icon = download.downloadImage(); //Returns A Bitmap image 
       loaded=true; //If no errors caught 
      } catch (Exceptions e) { 
       //Various Exception Handling Here 
      } 
      return null; 
     } 


     @Override 
     protected void onPostExecute(String result) { 
      super.onPostExecute(result); 
     } 


    } 

你能告訴我我需要適應哪些功能來實現這個功能嗎? 謝謝!

+0

PS我已經研究瞭如何設置圖像和我能做到這一點,如果我已經有我所有的位圖,但我不知道如何與後臺下載 – Edd

+1

所以,有一件事,你需要設置做到這一點圖像視圖(可能基於本地圖像路徑),如果圖像未找到,則將其保留爲佔位符,否則將圖像設置爲imageview。在AsyncTask的每個週期(即下載圖像)之後,只需調用Adapter.notifyDataSetChanged()。希望這可以幫助。 –

+0

你應該使用imageDownloader類........... – Piyush

回答

2

做到這一點,最簡單的方法是將您的圖像下載到一些Collection,然後下載是通過在Adapter調用notifyDatasetChanged完成後,列表更新。

在我們開始之前 - 我不知道您的AsyncTask位於何處。如果它是一個單獨的課程,則需要使用Interface來設置回撥到您啓動的地方。如果您的Adaper內的課程可以在本地進行。

你要做的是將你的Adapter設置爲(1)檢查你想要的圖像是否可用(2)如果沒有下載圖像並將其添加到集合(3)下載圖像時刷新列表(或者當所有圖像被下載時(取決於此列表的長度)。當你如果你AsyncTask是witin您adapater一個內部類,然後內onPostExecute你將(1)中的圖像添加到此集合設置特定列表項

if(logo != null){ 
    if(imageCollection.contains(key){ 
     logo.setImageBitmap(imageCollection.get(key)); 
    } else { 
     thumbnailDownloader.execute; 
    } 
} 

內容

這一切發生(2)使用notifyDatasetChanged更新ListView。如果您的AsyncTask是它自己的類,那麼您將在回調中將圖像添加到碰撞中,並從那裏更新列表。

對於collection如果您使用內置於android中的LruCache,但您可以使用HashMap或其他內容,則更容易。取決於你的實施。

+0

asyncTask是我的ListFragment類的一個子類,可能很容易,所以它可以訪問適配器可以訪問的任何數據 – Edd

1

首先,我會建議給ArticleAdapter參考AsyncTask
然後在ArticleAdapter中創建一個Bitmap數組或地圖,併爲ArticleAdapter創建一個add(Bitmap bmp)方法,該方法將位圖對象放入數組/地圖中。
因爲您在AsyncTask中有參考,所以您可以調用onPostExecute()方法中的add()方法,並下載圖標Bitma p。
然後你可以撥打ArticleAdapternotifyDataSetChanged(),這樣可以刷新它的觀點。

當然,如果已經下載了給定密鑰的位圖,那麼適配器的getView應檢查其位圖陣列/映射。如果它的引用是空的,則放置一個佔位符,如果已經下載了,則放置放置在數組/映射中的位圖由asynctask命名。

+0

如何通知DataSetChanged()肯定它必須是(一些對象).notifyDataSetChanged()即時通訊工作在一個ListFragment如果有幫助並沒有創建一個適配器對象我可以參考,我通過setListAdapter(new ArticleAdapter(getActivity(),strings,icons))設置適配器; – Edd

+0

沒關係,明白了:D – Edd

1

在getView()中,您應該啓動一個新任務來下載該列表項的圖像。將想要填充的ImageView的引用傳遞給AsyncTask,然後將該ImageView的源設置爲onPostExecute()中的下載位圖(圖標)。

這確實有點複雜,因爲您將不得不處理由ListView回收的視圖(通過取消下載圖像的任務)。我喜歡用這個庫來下載和緩存圖片:http://square.github.io/picasso/

0

這個答案很晚,但可能對其他人有幫助。

在你的代碼,如果你的AsyncTask<>位於作爲單獨的類,那麼你可以簡單地用你的適配器類給它ImageView實例化它,就像

new LoadThumbnail(imageView).execute(url); 

然後在LoadThumbnail類簡單地設置位圖imageView

我正在寫這篇文章,請按照你的意思寫;

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View rowView = inflater.inflate(R.layout.list_entry,parent,false); 
    TextView tv = (TextView) rowView.findViewById(R.id.label); 
    ImageView imageView = (ImageView)rowView.findViewById(R.id.logo); 
    tv.setText(values[position]); 

    //Instantiate LoadThumbnail giving it imageView to set bitmap in. 
    new LoadThumbnail(imageView).execute(url); 

    return rowView; 
} 

現在在onPostExecute()方法LoadThumbnail簡單地設置位圖。

protected class LoadThumbnail extends AsyncTask<String, Void, Bitmap> { 
     private ImageView imageView; 

     public LoadThumbnail(ImageView imageView){ 
      this.imageView = imageView; 
     } 

     @Override 
     protected String doInBackground(String... url) { 
      Bitmap icon = null; 
      Download download = new Download(url[0]); //My Download Class 
      try { 
       icon = download.downloadImage(); //Returns A Bitmap image 
       loaded=true; //If no errors caught 
      } catch (Exceptions e) { 
       //Various Exception Handling Here 
      } 
      return icon; 
     } 

     @Override 
     protected void onPostExecute(Bitmap icon) { 
      super.onPostExecute(icon); 

      //here set bitmap in imageView; 
      if(icon != null){ 
       imageView.setImageBitmap(icon); 
      } 
     } 
    } 
相關問題