2017安卓主流框架搭建姆蘸?看這篇就夠了(上)

  • 前言:記得那是2014年8月份13號,在親戚的鼓勵下延塑,C#轉(zhuǎn)android,自學了15天網(wǎng)上下載的“黑馬視頻”后答渔,懷著忐忑不安的心情被帶來了深圳关带,趕鴨子上架般接手了人生中的第一個android項目“橙果新聞”。當時毫無框架的概念沼撕,listview也沒有viewholder優(yōu)化宋雏,整個app可以說各種卡頓!然鵝务豺,磨总,,對于初學的我來講笼沥,當時的追求也只是app不閃退就好,哈哈蚪燕。
    轉(zhuǎn)眼三年有余,前段時間新公司app項目重構奔浅,采用的主框架正好是當下比較熱門的MVP+RXJava2+Retrofit2.0馆纳,當時由于時間緊任務重,粗略的看了看使用方法就開始編碼了乘凸,這段時間項目小版本迭代空閑時間多厕诡,于是決定將別人整理,封裝的框架自己再整理完善一下营勤,以后開發(fā)項目都可以用這一套熟練的進行開發(fā)了灵嫌!

構建順序:

1.常用基礎工具類(包括File,Bitmap葛作,字符串處理寿羞,圖片加載等,UI輔助等等)
2.基類BaseActivity赂蠢,BaseFragment的構建(titlebar,statebar,loadingview,defalutview四大模塊的封裝)
3.屏幕適配(圖片绪穆,長度)
4.mvp模式(使用MVPPluge插件,自動生成MVP的類文件以及該插件的改裝)
5.網(wǎng)絡框架的接入(RXJava2+Retrofit2.0)


6.gradle多環(huán)境配置(測試,預發(fā)布玖院,正式)
7.CI自動化打包上傳(jenkins+git+碼云or蒲公英)

*其中1,2,3跟業(yè)務邏輯關系不大菠红,我抽取出來作為一個lib,下載過去直接應用就行难菌。

本次系列文章试溯,本人一改之前懶得傳代碼的尿性,完整的demo項目地址將會在系列結束后貼上(目前還在整理中)郊酒,恩遇绞,拿去就用!你值得clone


一.常用工具類清單:

Base64Util:圖片文件與Base64互轉(zhuǎn)燎窘。
BaseBitmapUtil:處理圖片的壓縮摹闽,縮放,裁剪褐健,旋轉(zhuǎn)付鹿,并且含有代碼創(chuàng)建一些Drawable XML的方法
BaseConstant:定義一下常量
BaseFileUtil:文件的常用操作方法
BasePackageUtil:獲取包信息,檢查包名應用是否安裝等pack相關方法
BaseStringUtil:常規(guī)例如:手機號铝量,郵箱等的正則檢驗倘屹,全半角轉(zhuǎn)換,等字符串處理方法
DateUtil:給我時間戳~給你各種日期慢叨,時間
KeyboardHelper:專業(yè)處理軟鍵盤遮擋纽匙,軟鍵盤隱藏,顯示等
NetworkUtil:獲取網(wǎng)絡狀態(tài)等方法
PreferUtil:專業(yè)處理shareperder數(shù)據(jù)
UiUtil:.提供常見的獲取屏幕寬高拍谐、獲取各種資源等方法烛缔,px dp轉(zhuǎn)換,提供延時處理的Handle
這部分沒啥好說轩拨,都是一些常用的方法践瓷,開發(fā)必備,當然也不那么完善亡蓉,根據(jù)需求晕翠,后期再添加


二.(重點來了)基類BaseActivity,BaseFragment的構建:

一個功能完善砍濒,封裝優(yōu)雅的基類無疑可以很大程度上減少重復代碼淋肾,使得開發(fā)時可以專注于業(yè)務邏輯,而不是在什么導航欄啊爸邢,缺省頁啊樊卓,加載框啊之類的東西上反復花時間!BaseActivity里面封裝了titlebar,statebar,loadingview,defalutview四大模塊杠河,開發(fā)時界面Activity的相關的UI直接幾行代碼配置即可碌尔,十分方面浇辜。
且BaseFragment里面會獲取父容器activity,然后直接復用BaseActivity的各種方法唾戚。既然是重點柳洋,那么下面就來詳細講講四大模塊的封裝。

TitleBar

導航欄颈走,toolbar有自身的一些缺陷膳灶,還是感覺不夠靈活,所以自己封裝一個公用的TitleBar是很有必要的立由。
封裝過程:
1.畫一個導航欄布局layout,明確導航欄的基本組成序厉,這里我是直接封裝了三個Textview锐膜,由于Textview有一個drawableX屬性,這就使得每個Textview既能做純文本弛房,又能圖文混合道盏, 左右中,三個Textview文捶,基本夠用了荷逞。

2.定義一個BaseTitleBar接口,里面定義好常用方法:

 /*設置整體背景色*/
BaseTitleBar setBgColor(int color);

/*標題欄相關*/
BaseTitleBar setTitle(@StringRes int StringResId);

BaseTitleBar setTitle(String text);

BaseTitleBar setTitleIcon(@DrawableRes int drawableId);

BaseTitleBar setTitleTextColor(int color);


/*右側(cè)文本或按鈕相關*/
BaseTitleBar setRightText(String text);

BaseTitleBar setRightText(@StringRes int stringResId);

BaseTitleBar setRightIcon(@DrawableRes int drawableId);

BaseTitleBar showRightTextView();

BaseTitleBar hideRightTextView();

BaseTitleBar setRightTextColor(int color);

BaseTitleBar setRightTextClickListener(View.OnClickListener listener);


/*左側(cè)文本或按鈕相關*/
BaseTitleBar setLeftText(String text);

BaseTitleBar setLeftText(@StringRes int stringResId);

BaseTitleBar setLeftIcon(@DrawableRes int drawableId);

BaseTitleBar showLeftTextView();

BaseTitleBar hideLeftTextVeiw();

BaseTitleBar setLeftTextColor(int color);

BaseTitleBar setLeftTextClickListener(View.OnClickListener listener);

int getId();

OK,機智如你粹排,一看這些方法名字就懂了吧种远。

3.創(chuàng)建TitleBar,繼承FrameLayout顽耳,實現(xiàn)BaseTitleBar坠敷,具體的代碼就不貼了,之后自己看射富。

StateBar

關于狀態(tài)欄膝迎,網(wǎng)上有太多教程,太多方法胰耗,太多框架了限次,這里針對SDK>Build.VERSION_CODES.KITKAT,統(tǒng)一隱藏狀態(tài)欄柴灯,然后建個StateBar去覆蓋卖漫,StateBar的顏色自定義,還可以隱藏弛槐,效果感覺還不錯懊亡,就不去使用框架了,如果您對狀態(tài)欄要求比較高乎串,一定要多種效果店枣,一定要適配側(cè)滑等等 那你可以略過StateBar速警,自己去封裝下就好。
封裝過程:
1.定義接口BaseStateBar鸯两,明確需要提供的方法

void hide();

void show();

void setBackgroundColor(int color);

void setBackgroundDrawable(@DrawableRes int resId);

View getView();

int getId();

boolean isEnabled();

2.創(chuàng)建StateBar闷旧,實現(xiàn)BaseStateBar接口

至于具體在BaseActivity中如何去初始化StateBar,可以詳見BaseActivity代碼

Loadingview

終于到了Loadingview钧唐,想想還有點小激動忙灼!因為這次,再也不用gif钝侠,不用幀動畫该园,不同一張破圖旋啊轉(zhuǎn),用上了大名鼎鼎的lottie帅韧,然如您還沒有聽說過或者使用過lottie(好low啊里初,掩面偷笑中..)可以看看這篇簡單的介紹,內(nèi)有大量免費炫酷示例忽舟,down一下就進自己的app了双妨,,這X裝的豪不費功夫有木有叮阅?
http://www.reibang.com/p/15c18049f642

LoadingView的封裝相對簡單刁品,畫個xml,在baseactivity中提供兩個方法show浩姥,hide 你懂的挑随,重點就是引入了lottie,炫酷不止一點點~打了好多字及刻,這里放一段demo里用lottie實現(xiàn)的啟動動畫來緩解一下木有圖的尷尬吧镀裤!

SM-G9350_20170920211104.gif

缺省頁Defaultview

總結起來,app中的缺省頁其實無外乎以下幾種:
1.無網(wǎng)絡缺省頁面
2.網(wǎng)絡請求錯誤缺省頁
3.空數(shù)據(jù)缺省頁
另外除了缺省頁有時候只是toast一下缴饭,并不需要缺省頁暑劝,具體如何,得看業(yè)務颗搂,得聽產(chǎn)品的担猛!哈哈
這里針對最為復雜的情況做一下封裝,其他簡單情況自然好處理
復雜情況:

進入頁面一瞬掉咔嚓斷網(wǎng)丢氢,顯示帶有““”刷新看看”按鈕的無網(wǎng)絡缺省頁
點擊刷新看看請求網(wǎng)絡后服務錯拋出錯誤傅联,顯示網(wǎng)絡錯誤缺省頁,并且?guī)в邪粹o“再試試"
點擊再試試疚察,請求正常了蒸走,可是沒有業(yè)務數(shù)據(jù),顯示空數(shù)據(jù)缺省頁貌嫡,帶有按鈕“XXXX”
點擊按鈕XXXX比驻,響應別的業(yè)務邏輯

思路有兩種:
1.多個defaultview實例该溯,分別控制各個view的層級,顯示狀態(tài)
2.一個實例别惦,根據(jù)需要動態(tài)變換view中的文本狈茉,按鈕,圖片
對比一下就明白掸掸,思路1處理起來會比較麻煩氯庆,萬一有更復雜的情況需要繼續(xù)添加不同的defaultview
所以這次的框架中采用思路2,一個defaultview扰付,各種變換堤撵!

封裝過程和loading大同小異,只不過提供的方法會多一些羽莺,三個核心view
圖片Image粒督,文本Textview,按鈕Textview

BaseActivty中需要封裝的四個模塊已經(jīng)分析完禽翼,那么他們?nèi)绾畏庋b進BaseActivity里呢?
大家都知道族跛,ViewGroup有個Addview方法可以添加子類闰挡,那么在BaseActivity中設置一個根RelativeLayout,初始化添加StateBar和TitleBar后礁哄,將子界面的contentview添加到TitleBar下方:

  //mContainer為根RelativeLayout
  mContainer.addView(view, getLayoutParams());
  private RelativeLayout.LayoutParams getLayoutParams() {
    RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    if (titleBar != null) {
        lp.addRule(RelativeLayout.BELOW, titleBar.getId());
    } else if (stateBar.isEnabled()) {
        lp.addRule(RelativeLayout.BELOW, stateBar.getId());
    }
    return lp;
}

而LoadingView和DefaultVie在需要的時候直接addView進根RelativeLayout长酗,不用addrule。
到此為止桐绒,BaseActivity的封裝基本完成夺脾。至于BaseFragment中就更簡單了,除了DefultView之外茉继,其他的地方直接:

         public void XXXXX() {
          BaseActivity baseActivity = getBaseActivity();
          if (baseActivity != null) {
               baseActivity.XXXXX();
       }
  }

意思就是任何BaseActivity里面封裝過調(diào)度UI的方法在BaseFragment里直接通過獲取父容器Activity后復用一下咧叭。 可以是對于DefaultVie卻不能這么用,這是為神馬呢烁竭?哈哈菲茬,留個課后習題,歡迎留言里回答~


三.屏幕適配

網(wǎng)上關于anroid適配的文章太多太多派撕,這里就不去復制了婉弹,直接說簡單處理方法

適配圖片:使用mipmap系列文件夾放圖片,mipmap系統(tǒng)會在縮放上提供一定的性能優(yōu)化终吼,

讓UI切一套720P的圖(或者用ios 750的镀赌,如果UI太懶,你又搞不定他)际跪,放入mipmap-xhdpi文件夾 這一套其實就夠了商佛,不同分辨率手機上系統(tǒng)會自動去縮放喉钢,如果擔心高分辨率圖片變的模糊可以再適配一套xxx的,反正我的S7edge上基本看不出差別威彰。

長度適配:
多dimens.png

如圖出牧,簡單解釋一下,w300dp表示手機 分辨率和手機屏幕密度經(jīng)過計算后得出該手機寬度300dp
框架中設置了300-420范圍的寬度文件夾歇盼,絕對涵蓋了96%+主流的手機寬度舔痕。

像素px =dp* (屏幕密度/160)

一個720px的手機,如果屏幕密度是320豹缀,那么他的寬度用dp表示就是360dp伯复,會使用w360里面的dimen,而點開W360里面的deimens看一下

W360.png

我們設置的dp1正好也是1dp邢笙,那么如果UI按照720P給你標注啸如,你直接按標注的px除以2用dp就好。
你可能會問氮惯,如果我的手機不是W360的呢叮雳? 例如去年的機皇S7edge:

S7edge.png

按照公式像素px =dp* (屏幕密度/160)
算出 S7的屏幕寬度是1440/(534/160)= w431.46

系統(tǒng)會根據(jù)手機的寬度去選擇接近的尺寸文件夾(聽說是向下取,431的手機還是會用w420妇汗,不會用w440帘不?未實測哦),如果UI按照720P給你標注一個頭像Image的寬度是100px杨箭, 你還是除以2寞焙,用50dp

   <ImageView         
       android:layout_width="@dimen/dp50"
        android:layout_height="@dimen/dp50"
      />

注意,這時候是W420文件夾里的dp50哦互婿,同樣 打開看看

w420.png

可以看到捣郊,同樣取dp50,這時候設置的是58.3慈参, 然后你再算算
58.3/50 是不是 約= 420/360
至于明明是w431呛牲,可是取的是w420,或者一個w359的設備向下取到w340怎么辦懂牧?

joke.png

其實不用太糾結侈净,正常設備寬度350+,359和340差了屏幕寬度的1/17僧凤,也就是說如果50dp最多相差3dp畜侦,基本可以忽略。如果你不能接受這個說法躯保,那么我會繼續(xù)說服你旋膳,359-340也是極端情況了,哪里去找正好359的設備呢途事? 如果你還不服验懊,那你去建立一個w350擅羞,甚至w355的吧,誤差可以控制在1dp义图。
如果你真的打算這么做的話减俏,那你一定是處女座!處女座<罟ぁ娃承!

truth.png

處女座追求完美也沒有錯,至于w350怕篷,甚至w430+的dimens怎么產(chǎn)生的 其實很簡單历筝,網(wǎng)上有腳本,找來跑一下廊谓,或者直接一個for循環(huán)啊,比如wXXX的

  for(int i=1:i<500;i++){
    float value=XXX/360*i梳猪;
    Logger.d("<dimen name="dp"+i+">"+value+"dp</dimen>")

}

好了,篇幅原因蒸痹,上篇到此為止春弥,可能文中有些不準確或者錯誤的地方歡迎指出,大家一起進步叠荠!下個月25號見惕稻。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蝙叛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌公给,老刑警劉巖借帘,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異淌铐,居然都是意外死亡肺然,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門腿准,熙熙樓的掌柜王于貴愁眉苦臉地迎上來际起,“玉大人,你說我怎么就攤上這事吐葱〗滞” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵弟跑,是天一觀的道長灾前。 經(jīng)常有香客問我,道長孟辑,這世上最難降的妖魔是什么哎甲? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任蔫敲,我火速辦了婚禮,結果婚禮上炭玫,老公的妹妹穿的比我還像新娘奈嘿。我一直安慰自己,他們只是感情好吞加,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布裙犹。 她就那樣靜靜地躺著,像睡著了一般榴鼎。 火紅的嫁衣襯著肌膚如雪伯诬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天巫财,我揣著相機與錄音盗似,去河邊找鬼。 笑死平项,一個胖子當著我的面吹牛赫舒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播闽瓢,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼接癌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了扣讼?” 一聲冷哼從身側(cè)響起缺猛,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎椭符,沒想到半個月后荔燎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡销钝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年有咨,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒸健。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡座享,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出似忧,到底是詐尸還是另有隱情渣叛,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布盯捌,位于F島的核電站诗箍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜滤祖,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一筷狼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧匠童,春花似錦埂材、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至扬绪,卻和暖如春竖独,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挤牛。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工莹痢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人墓赴。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓竞膳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親诫硕。 傳聞我的和親對象是個殘疾皇子坦辟,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容