3、AsyncTask
new NewsTask().execute((Void)null);執行一個異步任務,也可以什麼參數也不傳。異步加載唱片的信息,調用相應的API,後面詳說API,加載成功則顯示唱片集的gallery,gallery中每一個item是一個自定義的ImageView,這個ImageView可以根據url異步加載唱片圖片並緩存,即com.teleca.jamendo.widget.RemoteImageView,後面詳說其實現。加載失敗則顯示retry,並彈出toast提示。
4、適配器adapter
在onResume()方法裡的fillHomeListView();這個就是用來填充listview的方法,我們可以看到這個listview中有兩種不同的布局,一種是類似分隔符的布局,一種就是可點擊的菜單項。先分析下可點擊的菜單項的adapter。
com.teleca.jamendo.adapter 包是適配器相關的類。
我們先看下ArrayListAdapter.java,它繼承自BaseAdapter,這個adapter中的數據集都是放在ArrayList<T> mList中的,子類繼承它覆寫自己的getView()方法,程序中可以通過adapter.setList(ArrayList<T> list)或者adapter.setList(T[] list)將特定類型的值填充進去。
可點擊的菜單項都是 ArrayListAdapter的一個子類:PurpleAdapter ,填充的類型則是<PurpleEntry>,PurpleEntry中有每一行的drawable和text以及點擊後觸發的操作。
下面就是整個list包括分隔符的總的adapter:SeparatedListAdapter。
[java]
SeparatedListAdapter separatedAdapter = new SeparatedListAdapter(this);
separatedAdapter.addSection(getString(R.string.browse_jamendo), mBrowseJamendoPurpleAdapter);
separatedAdapter.addSection(getString(R.string.my_library), mMyLibraryPurpleAdapter);
我們進到SeparatedListAdapter 中,看構造方法,先初始化了一個ArrayAdapter<String> headers,這個就是那個分隔符的adapter,addSection(String section, Adapter adapter)是給headers填充值,同時把上面的兩個PurpleAdapter 放入map中,再看下getCount()方法,可以看到這個listview總共的條目數,就是除了上面兩個PurpleAdapter 的數量,還要加上兩個分隔符。下面看下getView()方法,填充的時候主要是調用headers的getView()和每個PurpleAdapter 的getView()方法,主要是邏輯,仔細走流程看懂應該沒問題。
下面主要看下3個覆寫的方法:
[java]
public int getViewTypeCount()
public int getItemViewType(int position)
public boolean isEnabled(int position)
這三個方法呢 ,你注釋掉也是沒有關系的,程序也照樣能跑,前兩個方法主要是緩存listview中item需要用到的,分析源碼,在listview的setAdapter()方法中,有個mRecycler這個變量,看它的注釋可以知道,這個是用來緩存視圖避免下次layout時重新create。mRecycler是ListView的父類AbsListView的一個內部類。往下看,mRecycler.setViewTypeCount( mAdapter.getViewTypeCount( ) );這兒調用了getViewTypeCount()方法,為了初始化這個用於緩存視圖的ArrayList,當listview的在填充item時,會調用mRecycler.getScrapView(position),這個方法裡會調用getItemViewType(int position)方法,根據返回的類型得到相應的緩存的視圖,傳遞給adapter的getView()方法中的convertView,這樣就可以復用了。
回到程序裡,這個adapter中的getView()中並沒有使用緩存視圖即判斷convertView是否為空,而是直接生成每一個view,所以這裡覆寫這兩個方法主要是為了服務isEnabled(int position),這個方法是判斷這一行能否點擊的,用於分隔的headers是不能點擊的。當然如果你把這3個方法注釋掉了,headers就能點擊了,也不會出錯,回到HomeActivity的fillHomeListView()中,最後mHomeListView.setOnItemClickListener(mHomeItemClickListener);設置listview的點擊事件,如果你點擊分隔符headers,程序中會try住這個異常,所以也沒事。正常點擊的話會調用事先已經設置好的listener中的方法。
下篇分析music API。