前言
很久之前就在關(guān)注代碼家每日共享的學(xué)習(xí)資源晤揣,獲益匪淺屋确。
最近比較空閑纳击,并且想自己構(gòu)建一個完整項目,來了解自己的不足攻臀,剛好Gank提供了API焕数,于是決定一試。
項目地址:TigerGank
效果展示
頁面 | 效果 |
---|---|
首頁效果 | |
網(wǎng)絡(luò)狀態(tài) | |
每日詳情 |
第三方庫
控件綁定:ButterKnife
網(wǎng)絡(luò)請求:okhttp
事件分發(fā):EventBus
方法數(shù)量突破:multidex
Json解析:fastjson
圖片加載:Glide
圖片瀏覽控件:PinchImageView
項目框架
首先刨啸,整體的項目框架堡赔,采用MVP框架。
關(guān)于Android框架呜投,還是比較自由的加匈。根據(jù)需求去選擇自己喜歡的框架就可以。
這里我想加深一下自己對MVP框架的理解仑荐,于是選擇采用MVP框架雕拼。
關(guān)于MVC、MVP粘招、MVVM的框架含義啥寇,可以參考此篇短文,言簡意賅洒扎。
該項目的框架基本仿照Google開源的Android框架模板辑甜。
雖然存在一些差異,不過大同小異袍冷。
BaseActivity
一個好的基類磷醋,可以大大減少后續(xù)的工作量。
首先胡诗,我們來稍微屢一下全局的要求:
標題欄:基本所有頁面都會有邓线,但是有些頁面可能需要定制化,甚至可能沒有煌恢。
頁面控制:此處是一大頭骇陈,包括Loading、無網(wǎng)瑰抵、無數(shù)據(jù)你雌、數(shù)據(jù)展示等多種頁面樣式以及展示邏輯。
綜上二汛,我認為我們需要為BaseActivity設(shè)置一個layout文件婿崭,它持有ToolBar和各個狀態(tài)的頁面UI拨拓,并且可以控制頁面UI的展示時機。
在子Activity中逛球,繼承BaseActivity后只需設(shè)置數(shù)據(jù)UI的樣式即可千元。
接下來我們就開始構(gòu)建BaseActivity苫昌,首先來構(gòu)建BaseActivity的layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/c_ffffff"
android:orientation="vertical">
<!--ToolBar-->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/c_3f51b5"
android:minHeight="?attr/actionBarSize" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<!--Loading Page-->
<include
android:id="@+id/view_loading"
layout="@layout/view_loading"
android:visibility="gone" />
<!--無數(shù)據(jù) Page-->
<include
android:id="@+id/view_no_data"
layout="@layout/view_no_data"
android:visibility="gone" />
<!--無網(wǎng) Page-->
<include
android:id="@+id/view_no_net"
layout="@layout/view_no_net"
android:visibility="gone" />
<!--數(shù)據(jù) Page-->
<FrameLayout
android:id="@+id/view_data"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</FrameLayout>
</LinearLayout>
可以看到颤绕,它包括了ToolBar、LoadingPage祟身、無數(shù)據(jù)Page奥务、無網(wǎng)Page以及數(shù)據(jù)Page。
接下來我們在BaseActivity中對控件進行初始化袜硫,開始書寫頁面狀態(tài)的控制代碼氯葬。
此處各位看官要有意識,這些控制代碼婉陷,不應(yīng)存在于BaseActivit中帚称。
原因有很多,首先因為Activity是我們MVP的View層秽澳,它僅僅掌控UI變化的結(jié)果闯睹,而不應(yīng)該持有UI變化的邏輯判斷。其次担神,如果我們將來封裝BaseFragment楼吃,難道需要將這些邏輯代碼再寫一遍應(yīng)用至BaseFragment中嗎?
所以這里我決定在BaseActivity中創(chuàng)建成員變量PageController妄讯。每個Activity都會有一個獨立的PageController孩锡,它持有Activity,來通知Activity的UI變化亥贸,并且和Activity擁有相同的生命周期:
//頁面狀態(tài)控制器躬窜,每個頁面持有一個,使用弱引用來持有Activity
//存在于BaseActivity中炕置,無需手動控制荣挨,在頁面銷毀時自動釋放
public class PageController {
//Activity對象
private WeakReference<BaseActivity> weakActivity;
//當前頁面狀態(tài)
private int currentState;
public PageController(BaseActivity activity) {
weakActivity = new WeakReference<>(activity);
}
//銷毀方法
public void onDestory() {
if (weakActivity == null) {
return;
}
weakActivity.clear();
weakActivity = null;
}
}
接下來就開始構(gòu)建具體的頁面控制邏輯。
這個邏輯因人而異讹俊,我這里就不介紹自己構(gòu)建時的思路了垦沉,源碼里的注釋都有體現(xiàn)。
在完成PageController后仍劈,當你需要構(gòu)建BaseFragment時厕倍,僅僅需要將fragment.getAcitivty()傳遞至PageController中,就可以使用PageController了贩疙。
網(wǎng)絡(luò)請求
使用okhttp來作為本次開發(fā)的網(wǎng)絡(luò)請求底層讹弯。
再好的框架况既,想要適應(yīng)一個項目,必定需要進行定制化的封裝组民。
在封裝之前棒仍,先回想一下一次完整的網(wǎng)絡(luò)請求,注意我們項目是MVP框架:
用戶在Activity中發(fā)出請求—>調(diào)用Presenter層的網(wǎng)絡(luò)請求方法->調(diào)用Model層的網(wǎng)絡(luò)請求方法->傳遞給Presenter請求結(jié)果以及數(shù)據(jù)->傳遞給Activity結(jié)果以及數(shù)據(jù)
在MVP框架下臭胜,一次網(wǎng)絡(luò)請求基本就是這樣的了莫其。
不過這就牽扯到框架問題了,我們先回到網(wǎng)絡(luò)請求中耸三,不去考慮框架乱陡。
如何最大限度的抽象,是我們現(xiàn)在要著重考慮的仪壮。
并且還要考慮并發(fā)憨颠、緩存、異步同步等一系列事情积锅。
該項目的網(wǎng)絡(luò)請求封裝簡直不忍直視爽彤,基本是本著能用就行的思想來進行封裝的。缚陷。适篙。
我發(fā)現(xiàn)此處是我的薄弱項,在將來有空時我會好好學(xué)習(xí)的蹬跃。匙瘪。。蝶缀。
這里就不做過多介紹了丹喻,其實網(wǎng)上有很多基于okhttp封裝相當好的網(wǎng)絡(luò)請求框架,想使用的話也可以使用翁都。
TODO
到目前為止碍论,還有一些功能沒有開發(fā):
-
Activity切換動畫
Activity之間的切換看似一瞬間,其實我個人認為還是很重要的柄慰。上下配合的流程型頁面應(yīng)該使用左右橫屏進入和關(guān)閉鳍悠,給人一種流暢、步驟的感覺坐搔。兩個毫無關(guān)聯(lián)的頁面藏研,應(yīng)該給人一種打開全新界面的動畫感等等。
-
搜索功能
Gank的API中擁有搜索的API概行,該功能在后續(xù)會去實現(xiàn)蠢挡。
-
網(wǎng)絡(luò)請求優(yōu)化
從該項目當中,我發(fā)現(xiàn)自己對網(wǎng)絡(luò)請求的理解和Android文件存儲的方式存在很多問題,等到有空业踏,我會將網(wǎng)絡(luò)請求這邊重構(gòu)禽炬,包括添加File緩存、異步同步請求勤家、文件上傳接收請求等一系列基本功能腹尖。
-
RxJava+Retrofit
本項目當中沒有使用RxJava。在后期有空我會重新再寫一遍該項目伐脖,會使用RxJava和其他框架來實現(xiàn)热幔,這算是立一個flag吧。
結(jié)語
這一周的精力除了完成本職工作外晓殊,基本上都放到了TigerGank中断凶。
我會慢慢抽空繼續(xù)完善該項目伤提,這周就先這樣了巫俺。
開發(fā)過程中遇到很多瓶頸,解決瓶頸的代碼肯定是不優(yōu)雅的肿男。主要還是因為自己的水平太差介汹。
一起加油,感興趣的朋友也可以自己開發(fā)Gank舶沛。
感謝
上述所有第三方庫