自定義一個帶有ActionBar的主題:這樣既能夠得到ActionBar效果,又能夠本身調整ActionBar的顯示,如背景和字體等。下面主要是從新指定了tab_indicator。android
//在values/style.xml裏:actionbar_tab_indicator的內容省略,官方文檔有,很羅嗦。 <style name="CustomActionBarTheme" parent="@android:style/Theme.Holo.Light"> <item name="android:actionBarTabStyle">@style/MyActionBarTabs</item> </style> <!-- ActionBar tabs styles --> <style name="MyActionBarTabs" parent="@style/android:Widget.Holo.ActionBar.TabView"> <!-- tab indicator --> <item name="android:background">@drawable/actionbar_tab_indicator</item> </style>
讓Activity繼承FragmentActivity,定義一個繼承自FragmentStatePagerAdapter的子類——MyPagerAdapter,活動佈局中放置一個ViewPager填充整個界面。Activity.onCreate方法裏爲ActionBar設置屬性:markdown
ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true); //FragmentStatePagerAdapter的public Fragment getItem(int position)等相關方法正是配合ViewPager來完成 //整個界面裏切換Fragment的功能。它一直保持正在顯示的,和左右(若是有)2個Fragment實例。 //關聯viewPager和FragmentStatePagerAdapter實例 viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
在佈局文件,ViewPager內放置android.support.v4.view.PagerTabStrip控件,這樣能夠顯示ActionBar的tabs爲特殊的樣式,就是一直顯示「左、中、右」 3個tab指示器,左右滑動ViewPager切換Fragment時,或者點擊tab標籤時左右滾動來顯示更多其它的tab。(之後上圖。。。)app
ListView支持顯示多種類型的條目,而且能夠同時複用不一樣條目的view。假設咱們使用ListView顯示一個下載應用的列表界面,在ListView的底部顯示「加載更多」這樣的按鈕,那麼就是讓ListView同時顯示2種類型的條目。
ListView的getView方法正是咱們爲ListView提供要顯示條目的地方,爲了便於爲普通的條目對應的view對象添加更多的控制,能夠定義ViewHolder來組合View,並負責它的建立和狀態控制。async
爲顯示的「應用信息」列表條目定義AppInfoViewHolder,它包含一個name和icon,佈局文件item_appinfo是簡單的ImageView和TextView,其ViewHolder定義以下:ide
class AppInfoViewHolder{ ImageView icon; TextView name; View itemView; public AppInfoViewHolder(){ itemView = View.inflate(AppHelper.getContext(), R.layout.item_appinfo,null); icon = (ImageView)itemView.findViewById(R.id.appIcon); name = (TextView)itemView.findViewById(R.id.appName); //關聯當前Holder和View itemView.setTag(this); } public void setViewData(AppInfo info){ icon.setImageResource(info.getIconResId()); name.setText(info.getName()); } public View getView(){ return itemView; } }
以後定義「加載更多」的LoadMoreViewHolder:佈局
public class LoadMoreViewHolder { private View contentView; private View loadMore; private View loading; private Button bt_loadMore; OnLoadMoreExecute loadMoreListener; public LoadMoreViewHolder{ contentView = View.inflate(UIUtils.getContext(), R.layout.load_more, null); loadMore = contentView.findViewById(R.id.view_load_more); loading = contentView.findViewById(R.id.view_loading); bt_loadMore = (Button) contentView.findViewById(R.id.bt_load_more); //關聯當前Holder和View contentView.setTag(this); showLoadMore(); } public interface OnLoadMoreExecute{ void loadMore(LoadMoreHolder holder); } //設置「加載更多」的業務邏輯 public void setOnLoadMoreListener(OnLoadMoreExecute action){ loadMoreListener = action; if(loadMoreListener != null ){ bt_loadMore.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { loadMoreListener.loadMore(LoadMoreViewHolder.this); } }); } } public void showLoading(){ loading.setVisibility(View.VISIBLE); loadMore.setVisibility(View.INVISIBLE); } public void showLoadMore(){ loadMore.setVisibility(View.VISIBLE); loading.setVisibility(View.INVISIBLE); } public View getView(){ return contentView; } }
LoadMoreViewHolder提供加載更多和加載中兩種界面,當數據加載失敗或者沒有更多數據時,可使用Toast進行界面提示,固然也能夠動態改變「加載更多」按鈕的顯示文本。字體
上面的LoadMoreViewHolder顯示了使用ViewHolder來管理每一個列表條目對應的View是很是方便的,這樣可讓ListView的每一個條目的建立、狀態修改的代碼都集中在一個類中,若是不是使用ViewHolder來組合View,那麼對View狀態的修改的代碼就很容易分散地複雜起來。this
ListView的多條目類型複用,主要是getView、getViewTypeCount、getItemViewType和getCount搭配使用。設計
public class AppInfoAdapter extends BaseAdapter { List<AppInfo> infos; private final int ITEMTYPE_APP = 0;//條目類型對應的值範圍是:0 ~
private final int ITEMTYPE_MORE = 1; //顯示的條目總數 @Override public int getCount() { return infos.size() + 1; } //position處的條目的類型,條目類型對應的值範圍是:0 ~getViewTypeCount()
-1getViewTypeCount()
-1 @Override public int getItemViewType(int position) { if(position == infos.size()){ return ITEMTYPE_MORE; }else{ return ITEMTYPE_APP; } } //顯示條目的類型數 @Override public int getViewTypeCount() { return 2; } //根據position和convertView來建立或複用條目 @Override public View getView(int position, View convertView, ViewGroup parent) { int viewType = getItemViewType(position); View view = null; switch (viewType) { case ITEMTYPE_APP: AppInfoViewHolder appHolder = null; if(convertView == null){ appHolder = new AppInfoViewHolder(); }else{ appHolder = (AppInfoViewHolder) view.getTag(); } appHolder.setViewData(infos.get(position)); view = appHolder.getView(); break; case ITEMTYPE_MORE: if(convertView == null){ LoadMoreViewHolder moreHolder = new LoadMoreViewHolder(); moreHolder.setOnLoadMoreListener(new OnLoadMoreExecute(){ @Override public void loadMore(LoadMoreViewHolder holder){ asyncLoadMoreData(holder); } }); view = moreHolder.getView(); }else{ view = convertView; } break; } return view; } private void asyncLoadMoreData(LoadMoreViewHolder holder){ holder.showLoading(); new Thread(){ @Override public void run() { final List<AppInfo> newData = new AppInfoDao.getPageData(2); UIHelper.runOnUiThread(new Runnable(){ @Override public void run() { if(newData == null){ Toast.makeText(AppHelper.getContext(), "獲取失敗,稍後重試。", Toast.LENGTH_SHORT).show(); }else if(newData.size() == 0){ Toast.makeText(AppHelper.getContext(), "沒數據了,稍後重試。", Toast.LENGTH_SHORT).show(); }else{ infos.addAll(newData); notifyDataSetChanged(); } holder.showLoadMore(); } }); } }.start(); } }條目類型對應的值範圍是:0 ~getViewTypeCount()
-1getViewTypeCount()getViewTypeCount()
ListView能夠添加多種類型的顯示條目,常見的有頂部的輪播圖片,頂部下拉刷新,以及底部的加載更多等等。藉助ViewHolder來管理ListView要顯示的條目,代碼更容易集中,能夠針對不一樣的條目設計不一樣的Holder類。code