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中的解释是:
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>{}