HomeActivity的界面如下:
整个界面大体可以分为两个部分:上面的ViewFlipper和下面的ListView
备注一:ViewFlipper
界面的最上面的mViewFlipper中包含了mGallery、mProgressBar、mFailureBar,刚开始以为最上面部分的显示是通过不同状态下设置View的visibility 的VISIBLE, INVISIBLE, or GONE.来显示的,看完代码之后才知道是用的ViewFlipper这个空间实现的,代码显得更加清楚。
<com.teleca.jamendo.util.FixedViewFlipper
android:orientation="vertical" android:id="@+id/ViewFlipper"
android:layout_width="fill_parent" android:layout_height="75dip"
android:background="@drawable/gradient_dark_purple">
<!-- (0) Loading -->
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:layout_marginLeft="15dip" android:gravity="left|center_vertical">
<com.teleca.jamendo.widget.ProgressBar
android:id="@+id/ProgressBar" android:layout_width="wrap_content"
android:layout_height="wrap_content">
</com.teleca.jamendo.widget.ProgressBar>
</LinearLayout>
<!-- (1) Gallery -->
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:gravity="center">
<Gallery android:id="@+id/Gallery" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:spacing="0px" />
</LinearLayout>
<!-- (2) Failure -->
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:layout_marginLeft="15dip" android:gravity="left|center_vertical">
<com.teleca.jamendo.widget.FailureBar
android:id="@+id/FailureBar" android:layout_width="wrap_content"
android:layout_height="wrap_content">
</com.teleca.jamendo.widget.FailureBar>
</LinearLayout>
</com.teleca.jamendo.util.FixedViewFlipper>
在onCreate()里面启动一个AsyncTask来加载,根据不同的结果决定显示ViewFlipper的哪部分内容
private class NewsTask extends AsyncTask<Void, WSError, Album[]> {
@Override
public void onPreExecute() {
mViewFlipper.setDisplayedChild(0);
mProgressBar.setText(R.string.loading_news);
super.onPreExecute();
}
@Override
public Album[] doInBackground(Void... params) {
JamendoGet2Api server = new JamendoGet2ApiImpl();
Album[] albums = null;
try {
albums = server.getPopularAlbumsWeek();
} catch (JSONException e) {
e.printStackTrace();
} catch (WSError e){
publishProgress(e);
}
return albums;
}
@Override
public void onPostExecute(Album[] albums) {
if(albums != null && albums.length > 0){
mViewFlipper.setDisplayedChild(1);
ImageAdapter albumsAdapter = new ImageAdapter(HomeActivity.this);
albumsAdapter.setList(albums);
mGallery.setAdapter(albumsAdapter);
mGallery.setOnItemClickListener(mGalleryListener);
mGallery.setSelection(albums.length/2, true); // animate to center
} else {
mViewFlipper.setDisplayedChild(2);
mFailureBar.setOnRetryListener(new OnClickListener(){
@Override
public void onClick(View v) {
new NewsTask().execute((Void)null);
}
});
mFailureBar.setText(R.string.connection_fail);
}
super.onPostExecute(albums);
}
@Override
protected void onProgressUpdate(WSError... values) {
Toast.makeText(HomeActivity.this, values[0].getMessage(), Toast.LENGTH_LONG).show();
super.onProgressUpdate(values);
}
}
在这个AsyncTask中进行专辑的加载,在加载时onPreExecute()中mViewFlipper.setDisplayedChild(0);也就是上面xml代码中的(0) Loading部分,然后在doInBackground()中进行专辑的加载,当加载完之后onPostExecute(Album[] albums),然后根据加载专辑是否成功,选择相应的界面,是显示加载成功之后的(1) Gallery还是加载失败之后的(2) Failure。其实这里关键是这个空间ViewFlipper,在API中的解释是:
android.widget.ViewFlipper
Simple ViewAnimator
that will animate between two or more views that have been added to it. Only one child is shown at a time. If requested, can automatically flip between each child at a regular interval.
备注二:ListView包含多个Adapter
这个mHomeListView的adapter里面包含mBrowseJamendoPurpleAdapter、mMyLibraryPurpleAdapter了这两个adapter。程序中在onResume()里面调用fillHomeListView()进行listview数据的初始化。
// attach list data to adapters
mBrowseJamendoPurpleAdapter.setList(browseListEntry);
mMyLibraryPurpleAdapter.setList(libraryListEntry);
// separate adapters on one list
SeparatedListAdapter separatedAdapter = new SeparatedListAdapter(this);
separatedAdapter.addSection(getString(R.string.browse_jamendo), mBrowseJamendoPurpleAdapter);
separatedAdapter.addSection(getString(R.string.my_library), mMyLibraryPurpleAdapter);
mHomeListView.setAdapter(separatedAdapter);
mHomeListView.setOnItemClickListener(mHomeItemClickListener);
这里将网络数据的adapter:mBrowseJamendoPurpleAdapter和本地数据的adapter:mMyLibraryPurpleAdapter通过SeparatedListAdapter这个继承自BaseAdapter的类将这个两部分的adapter数据统一了起来,在外界调用者看来就只有一个SeparatedListAdapter,看着SeparatedListAdapter如何将两个adapter合二为一并分别给他们添加header的在后面在专门进行分析。
备注三:
在listview的item点击后都会跳到不同的activity中去,唯独只有Most listened这个显示收听的前一百名歌曲的这个item是首先在HomeActivity这个界面成功加载完数据然后才跳到相应的activity的。从用户的角度来说不能跳到了显示前一百名歌曲的Activity然后显示加载的ProgressBar然后加载成功还好要是加载不成功,那么要么返回HomeActivity要么在显示歌曲的界面显示无法获取,而这里是在HomeActivity就加载完了成功就跳转,不成功那么给提示还在HomeActivity这个界面。
这个Top100Task不是通过像之前那样集成AsyncTask来实现的,而是通过集成一个可以被复用的类来实现的private class Top100Task extends LoadingDialog<Void, Playlist>{}