高仿GooglePlay(一)
阿新 • • 發佈:2019-02-19
一,概述
這是高仿goole市場的一個專案。配有服務端。這裡我們只關注客戶端。由於CSDN對圖片大小有限制,有的功能沒演示出來。後續會一點點的貼出。基本效果如下:
二,分析
和市場上很多專案整體模式一樣。ViewPagerIndictor+ViewPager+Fragment。每個Fragment有個共同的特點:都需要載入資料,且都需要展示出來。那麼就可以抽取出來一個基類,LoadFragment。每個Fragment展示出來的UI有四種(載入資料UI,失敗UI,伺服器未給資料UI,成功UI):
共同點
- 載入資料UI
- 失敗的UI
- 伺服器未給資料UI
不同點:
- 資料成功UI
四種展示的UI可以通過自定義ViewGroup來管理實現(LoadUi)。LoadUI並不知道每個資料成功UI是什麼樣子,且基類LoadFragment也不知道。每個Fragment的成功UI是不同的。所以延遲到子類具體實現。
1.LoadUI有五種狀態以及上面提到的四種UI:
- 空狀態
- 載入中狀態
- 載入失敗狀態
- 載入為空狀態
- 載入成功狀態
public final static int STATE_NONE = 0;
public final static int STATE_LOADING = 1;
public final static int STATE_EMPTY = 2;
public final static int STATE_ERROR = 3;
public final static int STATE_SUCCESS = 4;
四種UI
private View mLoadingView;
private View mErrorView;
private View mEmptyView;
private View mSuccessView;
2.LoadUI的行為是:載入資料,根據載入返回來狀態來顯示更新UI
但LoadUi不清楚具體是怎麼樣載入資料的,Fragment也不清楚。和成功UI一樣,具體實現延遲到子類。
private class LoadDataTask implements Runnable {
@Override
public void run() {
SystemClock.sleep(3000);//模擬載入耗時操作
Result result = onLoadData();
mCurruntState = result.getState();
safeUpdateUI();
}
}
private void safeUpdateUI() {
UIUtils.getMainHandler().post(new Runnable() {
@Override
public void run() {
updateUI();
}
});
}
protected abstract View onLoadSuccessView();
protected abstract Result onLoadData();
前面提到了LoadFragment不知道每個子Fragment的成功UI是什麼樣子。也不知道每個子Fragment是如何具體載入資料的。所以都延遲到子類去實現。
protected abstract View startLoadSuccessView();
protected abstract LoadUi.Result startLoadUI();
三,類圖
四,細節的處理
通過FragmentFractory對Fragment集中管理,避免建立過多的物件。用了Google SparseArrayCompat取代HashMap
package com.yp2019cl.googlemarket.fragment;
import android.support.v4.util.SparseArrayCompat;
import com.yp2019cl.googlemarket.base.LoadFragment;
/**
* @專案名: GoogleMarket
* @包名: com.yp2019cl.googlemarket.fragment
* @類名: FragmentFractory
* @作者: yp
* @建立時間: 2016/03/17 23:12
* @描述: TODO:
*/
public class FragmentFractory {
private static SparseArrayCompat<LoadFragment> mCaches = new SparseArrayCompat<LoadFragment>();
private static LoadFragment mFragment;
public static LoadFragment getFragment(int position) {
mFragment = mCaches.get(position);
if (mFragment != null) {
return mFragment;
}
switch (position) {
case 0:
mFragment = new HomeFragment();
break;
case 1:
mFragment = new AppFragment();
break;
case 2:
mFragment = new GameFragment();
break;
case 3:
mFragment = new SubFragment();
break;
case 4:
mFragment = new RecommendFragment();
break;
case 5:
mFragment = new CategoryFragment();
break;
case 6:
mFragment = new HomeFragment();
break;
}
mCaches.put(position, mFragment);
return mFragment;
}
}
PagerAdapter getItem程式碼:
@Override
public Fragment getItem(int position) {
return FragmentFractory.getFragment(position);
}