完成基本的頁面
- 實現具體功能的frgment
對應相應的字符串:
<string-array name="home_titles">
<item>首頁</item>
<item>應用</item>
<item>遊戲</item>
<item>專題</item>
<item>推薦</item>
<item>分類</item>
<item>排行</item>
</string-array>
我們創建相應的fragmnet與之對應,在此之前我們先明確我們的需求:首先我們要從網絡訪問數據,然後顯示相應的視圖,那麼我們抽象出一個控制器,因爲從網絡訪問有不同的結果,如失敗、控、成功,那麼我們通過控制器來爲不同的狀態顯示數據,於是創建LoadingPager類:
加載數據的五種:
public static final int STATE_NONE = -1;
public static final int STATE_LOADING = 0;
public static final int STATE_EMPTY = 1;
public static final int STATE_ERROR = 2;
public static final int STATE_SUCCESS = 3;
fragment和loadingPager的關係如圖所示:
loadingPager的主要方法:
initCommentView()初始化公共視圖,也就是在loadingPager中添加view
private void initCommentView() {
mLoadingView = UIUtils.initView(R.layout.pager_loading);
this.addView(mLoadingView);
mErrorView = UIUtils.initView(R.layout.pager_error);
mErrorView.findViewById(R.id.error_btn_retry).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
loadData();
}
});
this.addView(mErrorView);
mEmptyView = UIUtils.initView(R.layout.pager_empty);
this.addView(mEmptyView);
refreshView();
}
那麼不可能能使顯示所有view,於是又利用控制器(就是狀態碼)來刷新視圖的方法refershView,注意三木運算符的使用:
private void refreshView() {
mLoadingView.setVisibility((mCurState == STATE_LOADING) || (mCurState == STATE_NONE) ? VISIBLE : GONE);
mEmptyView.setVisibility((mCurState == STATE_EMPTY) ? VISIBLE : GONE);
mErrorView.setVisibility((mCurState == STATE_ERROR) ? VISIBLE : GONE);
if (mSuccessView == null && mCurState == STATE_SUCCESS) {
mSuccessView = initSuccessView();
this.addView(mSuccessView);
}
if (mSuccessView != null) {
mSuccessView.setVisibility((mCurState == STATE_SUCCESS) ? VISIBLE : GONE);
}
}
由上面圖片可知假如加載成功那麼,loadingPager不顯示任何視圖,也可以說視圖是由fragment來提供的,那麼一定還有一個successView的方法來返回成功視圖。
再看和loadingPager相對應的各個fragment由於加載數據是每個fragment都是用的,所以抽取出公共baseFragment,在oncreateView中我們應該新建一個loadingPager對象來遮蓋住fragment,從而實現控制器的功能,這裏注意loadingPager是抽象類,所以要有匿名實現方法,具體如下:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mLoadingPager = new LoadingPager(UIUtils.getContext()) {
@Override
public LoadedResult initData() {
return BaseFragment.this.initData();
}
@Override
public View initSuccessView() {
return BaseFragment.this.initSuccessView();
}
};
return mLoadingPager;
}
這裏寫出兩個和loadingPager同名的方法,注意寫法是fragmnet.this.init()主要是便於理解,我們然後在實現每個frgment,完整的fragmnet代碼:
public abstract class BaseFragment extends Fragment {
private LoadingPager mLoadingPager;
public BaseFragment() {
// Required empty public constructor
}
public LoadingPager getLoadingPager() {
return mLoadingPager;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mLoadingPager = new LoadingPager(UIUtils.getContext()) {
@Override
public LoadedResult initData() {
return BaseFragment.this.initData();
}
@Override
public View initSuccessView() {
return BaseFragment.this.initSuccessView();
}
};
return mLoadingPager;
}
protected abstract LoadingPager.LoadedResult initData();
public abstract View initSuccessView();
}
利用工廠模式獲得fragmnet
我們新建出每個fragment但是假如一個一個new出來很麻煩於是,於是再次用整數的狀態碼,來創建並且返回不同的fragment,具體代碼:
public class FragmentFactory {
public static final int FRAGMENT_HOME = 0;
public static final int FRAGMENT_APP = 1;
public static final int FRAGMENT_GAME = 2;
public static final int FRAGMENT_SUBJECT = 3;
public static final int FRAGMENT_RECOMMEND = 4;
public static final int FRAGMENT_CATEGORY = 5;
public static final int FRAGMENT_HOT = 6;
static SparseArray<BaseFragment> cacheFragment = new SparseArray<BaseFragment>();
public static BaseFragment getFragment(int position) {
BaseFragment fragment = null;
BaseFragment tmpFragment = cacheFragment.get(position);
if (tmpFragment != null) {
fragment = tmpFragment;
return fragment;
}
switch (position) {
case FRAGMENT_HOME:// 主頁
fragment = new HomeFragment();
break;
case FRAGMENT_APP:// 應用
fragment = new AppFragment();
break;
case FRAGMENT_GAME:// 遊戲
fragment = new GameFragment();
break;
case FRAGMENT_SUBJECT:// 專題
fragment = new SubjectFragment();
break;
case FRAGMENT_RECOMMEND:// 推薦
fragment = new RecommendFragment();
break;
case FRAGMENT_CATEGORY:// 分類
fragment = new CategoryFragment();
break;
case FRAGMENT_HOT:// 排行
fragment = new HotFragment();
break;
default:
break;
}
cacheFragment.put(position, fragment);
return fragment;
}
}