2012-04-09 55 views
1

我試圖下載每個擁有手機音樂的藝術家的圖像,然後在GridView中顯示這​​些圖像。我正在使用Last.fm建議使用的lastfm-java library。您調用來獲取藝術家圖像的方法是getImageURL(ImageSize size),但在執行此操作之前,您需要通過參數String來告訴它要引用哪個藝術家。所以,完全會是這樣的:將光標與AsyncTask一起使用

@Override 
protected String doInBackground(Object... arg0) { 
    Artist artist = Artist.getInfo(artistOrMbid, LASTFM_API_KEY); 
    return artist.getImageURL(ImageSize.EXTRALARGE);  
} 

讓所有屬於我的手機上的藝術家是沒有問題的,你剛纔提到MediaStore。你會做這樣的事情:

private void getArtists() { 
    String[] projection = new String[] { 
      MediaStore.Audio.Artists._ID, MediaStore.Audio.Artists.ARTIST, 
    }; 
    String sortOrder = MediaStore.Audio.Artists.DEFAULT_SORT_ORDER; 
    Cursor c = getActivity().getContentResolver().query(
      MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, projection, null, null, sortOrder); 
    if (c != null) { 
     int count = c.getCount(); 
     if (count > 0) { 
      final int ARTIST_IDX = c.getColumnIndex(MediaStore.Audio.Artists.ARTIST); 
      for (int i = 0; i < count; i++) { 
       c.moveToPosition(i); 
      } 
     } 
     c.close(); 
     c = null; 
    } 
} 

AdapterGridView沒有什麼特別的,它只是擴展BaseAdapter

注意AQuery是我使用,可以幫助緩存和從URL加載一個Bitmap庫。

public class GridViewAdapter extends BaseAdapter { 

private final String[] imageURLs; 

private final LayoutInflater mInflater; 

private final Activity mActivity; 

public GridViewAdapter(String[] urls, Activity activity) { 
    imageURLs = urls; 
    mActivity = activity; 
    mInflater = (LayoutInflater)mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

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

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

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

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

    ViewHolder viewholder = null; 

    // Inflate GridView items 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.gridview_items, null); 
     viewholder = new ViewHolder(); 
     viewholder.mImage = (ImageView)convertView.findViewById(R.id.gridview_image); 
     convertView.setTag(viewholder); 
    } else { 
     viewholder = (ViewHolder)convertView.getTag(); 
    } 

    AQuery aq = new AQuery(convertView); 

    aq.id(viewholder.mImage).image(imageURLs[position], false, false, 0, 0, null, 0, 0.75f); 

     return convertView; 
    } 

} 

class ViewHolder { 
    public ImageView mImage; 
} 

所以滿,我AsyncTask如下:

public class LastfmArtistGetImageURL extends AsyncTask<Object, Integer, String[]> implements 
    Constants { 

private static final String tag = LastfmArtistGetImageURL.class.getSimpleName(); 

private GridViewAdapter mGridAdapter; 

// Test 
private final String[] imageIds = { 
     "http://userserve-ak.last.fm/serve/252/71875544.png", 
     "http://userserve-ak.last.fm/serve/252/6258507.jpg", 
     "http://userserve-ak.last.fm/serve/252/51274303.png", 
     "http://userserve-ak.last.fm/serve/252/58672183.png", 
     "http://userserve-ak.last.fm/serve/252/72029714.png", 
     "http://userserve-ak.last.fm/serve/252/17666215.jpg", 
     "http://userserve-ak.last.fm/serve/252/63247381.png", 
     "http://userserve-ak.last.fm/serve/252/33665463.jpg" 
}; 

private final String artistOrMbid; 

private final GridView mGridView; 

private final Activity mActivity; 

public LastfmArtistGetImageURL(String name, GridView gv, Activity activity) { 
    artistOrMbid = name; 
    mGridView = gv; 
    mActivity = activity; 
} 

@Override 
protected String[] doInBackground(Object... arg0) { 
    Artist artist = Artist.getInfo(artistOrMbid, LASTFM_API_KEY); 
    Collection<String> col = new ArrayList<String>(); 
    col.add(artist.getImageURL(ImageSize.EXTRALARGE)); 
    return col.toArray(new String[0]); 
} 

@Override 
protected void onPostExecute(String[] result) { 
    if (result != null) 
     mGridAdapter = new GridViewAdapter(imageIds, mActivity); 
    mGridView.setAdapter(mGridAdapter); 
    super.onPostExecute(result); 
    } 
} 

當我打電話給我AsyncTask,我把它在我的getArtists()方法是這樣的:

new LastfmArtistGetImageURL(c.getString(ARTIST_IDX), mGridView, getActivity()) .execute();

問題

當我打電話給這個時候,所有的藝術家圖片都下載了,但是他們一個接一個地下載我的GridViewAdapterposition 0。換句話說,當我需要將它們放入GridView中的每個可用position中時,首先加載一個圖像,然後下一個,等等全部在第一個position中。當我在我的AsyncTask中返回我的測試String[]時,一切正常。所有圖像按照GridView的每個可用空間順序排列。

問題

我的問題是,我該如何正確地在我的GridViewAdapter返回每個藝術家圖像我下載到我的GridView和爲什麼圖像目前只裝載在第一position

編輯 - Shubhayu的答案 我感動設置我的GridViewAdapter到我getArtists()方法如下所示。這導致下載的所有圖像(如LogCat所示),但只有最後一個被設置在我的GridView中。

String[] test = new LastfmArtistGetImageURL(c.getString(ARTIST_IDX), 
mGridView, getActivity()).execute().get(); 
mGridAdapter = new GridViewAdapter(test, getActivity()); 
mGridView.setAdapter(mGridAdapter); 

smoak的回答 這導致只有最後一個藝術家圖像(由默認順序)下載並在我GridView應用。

String[] test = {c.getString(ARTIST_IDX)}; 
new LastfmArtistGetImageURL(test, mGridView, getActivity()).execute(); 
+0

是否在循環中調用LastfmArtistGetImageURL()以覆蓋光標中的所有藝術家?併爲每個電話回來多少圖片?我假設每個藝術家1人。 – Shubhayu 2012-04-09 05:28:41

+0

GridView期待的是一系列圖像,但是當你將一個圖像傳遞到另一個圖像時,它將被放置在第0個位置。立即返回完整數組並調用GridView適配器。那麼它會按預期工作 – user1203673 2012-04-09 05:30:38

+0

@Shubhayu是的,沒錯。下載所有圖像不是問題,將它們正確放置在我的'Adapter'中。 @ user1203673因爲這個原因,我的'AsyncTask'返回一個'String []',當我使用我的測試'String []'時,一切正常,所以我不確定我明白你的意思。 – adneal 2012-04-09 05:42:06

回答

1

AsyncTask看起來你對每個藝人每次執行它。因此,您的AsyncTask只會返回一個藝術家的圖像,而您的GridView會獲取該藝術家的圖像,然後您會爲下一個藝術家運行AsyncTaskGridView會更新新圖像等等。你需要做的是修改你的AsyncTask以獲取藝術家姓名的字符串數組,並在doInBackground中循環查看他們的圖像。

// ... SNIPPED 

public LastfmArtistGetImageURL(String[] names, GridView gv, Activity activity) { 
    artistsOrMbids = names; 
    mGridView = gv; 
    mActivity = activity; 
} 

@Override 
protected String[] doInBackground(Object... arg0) { 
    Collection<String> col = new ArrayList<String>(); 
    for (String nameOrMbid : this.artistsOrMbids) { 
     Artist artist = Artist.getInfo(artistOrMbid, LASTFM_API_KEY); 
     col.add(artist.getImageURL(ImageSize.EXTRALARGE)); 
    } 
    return col.toArray(new String[0]); 
} 


// .... SNIPPED 

並傳遞所有的藝術家姓名:

String[] artists = { "The Black Keys", "Rush", "The Allman Brothers" }; 
new LastfmArtistGetImageURL(artists, mGridView, getActivity()).execute(); 
+0

啊,賓果。非常感謝,長期以來一直困擾着我。我非常感激,這正是我所需要的。 – adneal 2012-04-09 06:22:16

+0

編輯 - 我說得太快了。我感覺有點傻。當我運行這個時,我忘記刪除我的測試'String []'。當我運行它時;但是,它只下載並返回最後一位藝術家。我把它傳入我的'AsyncTask'中;''這是你在說什麼? – adneal 2012-04-09 06:28:10

+0

我編輯了我的OP與您的答案的結果。 – adneal 2012-04-09 06:52:15

1

這裏發生了什麼,當你通過測試串它具有圖像列表,因此在GridView正確顯示它們。但是當您使用它爲每位藝術家下載圖像時,情況就會出錯。

每次通話時間

新LastfmArtistGetImageURL(c.getString(ARTIST_IDX),mGridView,getActivity())執行()。

它運行的doInBackground(),完成它,然後立即調用onPostExecute()在那裏創建一個新的適配器,並將你的結果基本上包含單電單圖像。

所以你需要做的是在你的asynctask下載所有圖像,然後創建一個適配器並將所有圖像傳遞給它。目前沒有發生這種情況。

編輯

如果你看到的AsyncTask,你會發現你稱呼它每次的字符串數組只返回一個圖像。所以不是返回一個字符串數組,而是返回一個字符串。

接下來,我建議你在你的Adapter中使用ArrayList而不是String數組。 。 在你getArtists(),創建一個ArrayList,每次你打電話

新LastfmArtistGetImageURL(測試,mGridView,getActivity())執行();

將結果添加到您的ArrayList中。一旦你瀏覽了所有的藝術家,你的ArrayList將包含所有的圖像。

現在將其設置爲適配器。 (如果將它從字符串更改爲arraylist,您將不需要更改適配器。)

+0

我在'Fragment'中設置了'Adapter'而不是'AsyncTask',並在'execute()'後面調用'get()'來返回整個String Array,然後將它傳遞到我的'Adapter' ,但它只會下載並返回最新的藝術家圖像。 – adneal 2012-04-09 06:37:18

+0

我編輯了我的OP與您的答案的結果。 – adneal 2012-04-09 06:52:03

+0

更新了評論。它應該照顧尿素問題。 – Shubhayu 2012-04-09 07:14:27