先扯兩句
其實(shí)按照正常情況阿浓,這篇博客應(yīng)該是在上一篇之前發(fā)的,實(shí)在是之前公司遇到了一個(gè)新需求稿蹲,要?jiǎng)?chuàng)建一個(gè)背景透明的Activity做提示遮罩用,結(jié)果現(xiàn)有的BaseActivity布局的封裝實(shí)在不支持這種情況设哗,所以只能創(chuàng)建了一個(gè)不是基于BaseActivity的Activity已達(dá)成需求,雖然任務(wù)完成了,可是程序員探索的腳步不能停烦感,于是痛定思痛之下,終于下定決心膛堤,對(duì)BaseActivity進(jìn)行拆解手趣,原本的BaseActivity保留所有的方法邏輯,而將與布局相關(guān)的方法與參數(shù)遷移到當(dāng)前的BaseLayoutActivity中肥荔。
好了绿渣,閑言少敘,老規(guī)矩還是先上我的Git燕耿,然后開始正文吧。 MyBaseApplication (https://github.com/BanShouWeng/MyBaseApplication)
正文
前面翻過(guò)android開發(fā)相關(guān)——include、merge和ViewStub的布局優(yōu)化中已經(jīng)闡述了ViewStub相關(guān)的內(nèi)容阀捅,沒有看到的朋友可以去看一下,而這里,我本次封裝的引用就從include替換到了ViewStub西土。當(dāng)然,這里也有一些需要提前說(shuō)明历帚,那就是一般而言,ViewStub使用的環(huán)境還是那些不常使用到的野来,例如引導(dǎo)頁(yè)之類的功能,而title的使用頻率還是蠻高的。而ViewStub解析所消耗的資源與無(wú)用的include占用的資源哪個(gè)更多苦蒿,以我當(dāng)前的水準(zhǔn)還無(wú)法得到一個(gè)準(zhǔn)確的答案秉溉,所以具體是使用ViewStub還是使用include還是看大家自己的理解了尝苇。當(dāng)然谊惭,如果誰(shuí)有更具體的數(shù)據(jù)众眨,也歡迎分享,在此感激不盡让蕾。
BaseActivity的底層封裝
首先神帅,這里先看一下BaseActivity的布局xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.banshouweng.mybaseapplication.base.activity.BaseActivity">
<ViewStub
android:id="@+id/base_title_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout="@layout/title_include" />
<FrameLayout
android:id="@+id/base_main_layout"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"/>
</LinearLayout>
其中只有兩個(gè)控件:其一為在前面寫的說(shuō)過(guò)的ViewStub控件霎桅,在這里的主要作用就是封裝的title布局文件;其二則是一個(gè)FrameLayout控件奄容,其作用嘛血柳,就是用以展示BaseActivity子類中重寫getLayout()方法時(shí)傳來(lái)id對(duì)應(yīng)的布局文件击敌。 實(shí)現(xiàn)方法,在《一個(gè)Android工程的從零開始》階段總結(jié)與修改3-BaseActivity上(抽象處理)中拴事,我們將BaseActivity做了抽象處理沃斤,其中使用到了一個(gè)方法在onCreate方法中調(diào)用了setBaseContentView(getLayoutId());如下圖標(biāo)注的位置圣蝎。
而這個(gè)方法的具體實(shí)現(xiàn)如下。
/**
* 引用頭部布局
*
* @param layoutId 布局id
*/
private void setBaseContentView(int layoutId) {
FrameLayout layout = getView(R.id.base_main_layout);
//獲取布局衡瓶,并在BaseActivity基礎(chǔ)上顯示
final View view = getLayoutInflater().inflate(layoutId, null);
//關(guān)閉鍵盤
hideKeyBoard();
//給EditText的父控件設(shè)置焦點(diǎn)徘公,防止鍵盤自動(dòng)彈出
view.setFocusable(true);
view.setFocusableInTouchMode(true);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
layout.addView(view, params);
}
可以看到,這里就是將傳遞來(lái)的子布局添加到FrameLayout中哮针,而看過(guò)我之前博客关面,或者下載我封裝的MyBaseApplication 的朋友會(huì)知道,當(dāng)時(shí)使用的是LinearLayout而不是現(xiàn)在的FrameLayout十厢。這真不是我閑的蛋疼等太,沒事非要亂改,畢竟我沒事就以懶漢自居蛮放,這是看過(guò)我博客的朋友都知道的缩抡,之所以改了名字完全是因?yàn)榘⒗餂]事非要發(fā)個(gè)什么《阿里巴巴Android開發(fā)手冊(cè)》,為了生存嘛筛武,肯定要向大公司開發(fā)規(guī)范靠攏嘍缝其。
四、UI 與布局
- 【推薦】靈活使用布局徘六,推薦 Merge内边、ViewStub 來(lái)優(yōu)化布局,盡可能多的減少 UI 布局層級(jí)待锈,推薦使用 FrameLayout漠其,LinearLayout、RelativeLayout 次之竿音。
想必對(duì)于像我這種菜鳥而言和屎,在使用布局的時(shí)候第一反應(yīng),還是使用的LinearLayout春瞬,等慢慢熟悉了之后忽然發(fā)現(xiàn)柴信,很多情況下RelativeLayout比LinearLayout更好用,而現(xiàn)在又出來(lái)了一個(gè)ConstraintLayout宽气。但是卻很少有使用到FrameLayout的随常,或許大家在培訓(xùn)的時(shí)候知道,在創(chuàng)建Fragment的時(shí)候使用FrameLayout去占位萄涯,可一般老師也不說(shuō)為什么绪氛。 之所以很少使用FrameLayout,并不是FrameLayout太難了涝影,而是它太簡(jiǎn)單了枣察,沒辦法完成我們所需求的那么多功能,而也正因?yàn)樗暮?jiǎn)單,才是我們這里使用它的原因序目,因?yàn)槭褂盟梢詼p少不必要的資源浪費(fèi)臂痕。通俗舉例(但不一定完全正確):RelativeLayout的相對(duì)關(guān)系處理在這里就用不上,所以多加載了這些功能宛琅,就是浪費(fèi)了資源刻蟹。 其中除了加載布局就是在防止鍵盤彈出逗旁,當(dāng)然嘿辟,也不是去掉這幾行代碼就一定會(huì)彈出輸入法,只是針對(duì)個(gè)別會(huì)自動(dòng)彈出的機(jī)型做了一下統(tǒng)一片效,去掉也可以红伦。 在子類中調(diào)用的時(shí)候,只需要重新抽象方法getLayoutId()即可:
@Override
protected int getLayoutId() {
return R.layout.activity_main;
}
如圖淀衣,上面就是在activity_base.xml中自定義的title昙读,而下面的則是activity_main.xml的布局。
title封裝
這里的title就是上面ViewStub對(duì)應(yīng)的布局文件膨桥,title布局文件title_include.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/title_height">
<RelativeLayout
android:id="@+id/base_bg"
android:layout_width="match_parent"
android:layout_height="@dimen/title_height"
android:background="@color/blue">
<ImageView
android:id="@+id/base_back"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="@dimen/size_13"
android:src="@mipmap/back"
android:tint="@android:color/white" />
<ImageView
android:id="@+id/base_close"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="@dimen/size_13"
android:src="@mipmap/close"
android:visibility="gone"
android:layout_toRightOf="@+id/base_back"
android:tint="@android:color/white" />
<TextView
android:id="@+id/base_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:text="@string/title"
android:textColor="@android:color/white"
android:textSize="@dimen/size_20" />
<ImageView
android:id="@+id/base_right_icon2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_toLeftOf="@+id/base_right_icon1"
android:contentDescription="@string/second_function_key"
android:padding="@dimen/size_13"
android:src="@mipmap/add"
android:tint="@android:color/white"
android:visibility="gone" />
<ImageView
android:id="@+id/base_right_icon1"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:contentDescription="@string/first_function_key"
android:padding="@dimen/size_13"
android:src="@mipmap/more"
android:tint="@android:color/white"
android:visibility="gone" />
<TextView
android:id="@+id/base_right_text"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:gravity="center"
android:text="@string/make_sure"
android:textColor="@android:color/white"
android:textSize="@dimen/size_17"
android:visibility="gone" />
</RelativeLayout>
</RelativeLayout>
ViewStub的運(yùn)用
開篇中已經(jīng)提到了蛮浑,我前面寫的寫的布局優(yōu)化的內(nèi)容,而關(guān)于ViewStub的運(yùn)用只嚣,實(shí)際在其中已經(jīng)闡述了沮稚,這里之所以還要拿出來(lái)說(shuō)一下,不是有新內(nèi)容册舞,也不是水字?jǐn)?shù)(畢竟也不是寫網(wǎng)文)蕴掏,只是單純的怕大家還需要去前面寫的博客查代碼比較麻煩而已,當(dāng)然這里就不多廢話了调鲸,直接把代碼貼在這里就好了盛杰。
/**
* Title ViewStub
*/
private ViewStub titleStub;
/**
* 控件初始化
*/
protected void initBaseView() {
if (titleStub == null) {
titleStub = getView(R.id.base_title_layout);
titleStub.inflate();
}
}
關(guān)閉按鈕
或許有人看到過(guò)我《一個(gè)Android工程的從零開始》-6、base(五) BaseFragment封裝中藐石,對(duì)于title的封裝即供,其實(shí)若對(duì)比下來(lái)的話,實(shí)際上還是那些內(nèi)容于微,只是比當(dāng)初封裝的時(shí)候多出了一個(gè)控件而已逗嫡,就是:
<ImageView
android:id="@+id/base_close"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="@dimen/size_13"
android:src="@mipmap/close"
android:visibility="gone"
android:layout_toRightOf="@+id/base_back"
android:tint="@android:color/white" />
而這個(gè)控件就是下圖中的“X”,在返回鍵的右側(cè)角雷,具體功能就是關(guān)閉:
關(guān)閉按鈕的作用
可能會(huì)有人問(wèn)祸穷,既然已經(jīng)有了返回鍵,為什么還要添加一個(gè)關(guān)閉鍵勺三,這樣是不是有些多此一舉雷滚。當(dāng)然,在大多數(shù)情況下吗坚,這個(gè)關(guān)閉確實(shí)是用不到的祈远,所以之前我也沒設(shè)置這個(gè)按鈕呆万,可隨著開發(fā)的項(xiàng)目越來(lái)越復(fù)雜,功能逐漸完善车份,就會(huì)發(fā)現(xiàn)谋减,其實(shí)這個(gè)“X”的存在還是很有價(jià)值的,下面我就舉兩個(gè)例子:
1.在多級(jí)菜單一次關(guān)閉的情況下扫沼,我在京東上查筆記本電腦出爹,目錄如下:電腦、辦公>電腦整機(jī)>筆記本>小米(MI) >小米Air缎除,結(jié)果發(fā)現(xiàn)買不起严就,想要買一箱啤酒借酒消愁的時(shí)候,還需要一級(jí)一級(jí)返回到“電腦器罐、辦公”的上一級(jí)重新搜索(別說(shuō)可以直接搜尋想要購(gòu)買的商品梢为,這里只是在說(shuō)明目錄結(jié)構(gòu)復(fù)雜時(shí)的情況),而如果有了這個(gè)“關(guān)閉鍵”則可以直接關(guān)閉掉這一系列頁(yè)面轰坊,直接跳轉(zhuǎn)到首頁(yè)去進(jìn)行后續(xù)操作铸董。
2.當(dāng)使用WebView訪問(wèn)的時(shí)候,一般我們會(huì)在用戶點(diǎn)擊返回鍵(自定義返回鍵肴沫、物理返回鍵粟害、或者虛擬返回鍵)的時(shí)候做如下代碼處理:
if(webView.canGoBack()){
webView.goBack();
return true;
}else{
finish();
return false;
}
其目的就是當(dāng)我們?cè)贖5頁(yè)面中訪問(wèn)到如下目錄時(shí):電腦、辦公>電腦整機(jī)>筆記本>小米(MI) >小米Air時(shí)樊零,想要再查看其它小米產(chǎn)品我磁,就可以直接點(diǎn)擊返回鍵,而不是返回鍵直接退出了當(dāng)前的WebView頁(yè)面驻襟,不然如果我是用戶夺艰,退出后做的第一件事就是把這個(gè)APP卸載了。可這樣就會(huì)造成一個(gè)問(wèn)題,當(dāng)用戶想退出WebView執(zhí)行APP其他操作的時(shí)候讨盒,卻需要將之前自己訪問(wèn)的頁(yè)面都返回一遍,這樣的用戶體驗(yàn)會(huì)不會(huì)再次有一批想要卸載APP的呢存谎?而這個(gè)時(shí)候,在我們無(wú)法智能到讀取用戶真實(shí)想法的情況下肥隆,就只能采取設(shè)置兩個(gè)按鈕的方法既荚,一個(gè)是返回上一級(jí),一個(gè)是關(guān)閉當(dāng)前WebView頁(yè)栋艳。
關(guān)閉按鈕的實(shí)現(xiàn)
根據(jù)上面的分析恰聘,我們知道了關(guān)閉按鈕常用的兩種情況,而若說(shuō)實(shí)現(xiàn)起來(lái),也是兩種情況晴叨。第一種情況下凿宾,點(diǎn)擊關(guān)閉按鈕的時(shí)候進(jìn)行的是批量關(guān)閉Activity的操作;而第二種情況則只是簡(jiǎn)單的關(guān)閉當(dāng)前WebView所在的Activity而已兼蕊。
1.批量關(guān)閉Activity
/**
* 關(guān)閉按鈕
*/
private ImageView baseClose;
/**
* 設(shè)置關(guān)閉部分頁(yè)面
*
* @param targetActivity 關(guān)閉后所要返回的Activity對(duì)應(yīng)的class
*/
public void setBaseClose(final Class<?> targetActivity) {
initBaseView();
baseClose = getView(R.id.base_close);
baseClose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
backTo(targetActivity);
}
});
}
首先initBaseView()方法自然是解析的title布局初厚,隨后是獲取baseClose控件,并添點(diǎn)擊事件孙技。其中的backTo(targetActivity)产禾,是批量關(guān)閉Activity的方法,back的具體實(shí)現(xiàn)方法會(huì)在下一篇博客中詳細(xì)說(shuō)明绪杏。
2.關(guān)閉當(dāng)前的Activity
/**
* 設(shè)置關(guān)閉點(diǎn)擊事件
*/
public void setBaseClose() {
initBaseView();
baseClose = getView(R.id.base_close);
baseClose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
}
看到這個(gè)方法打擊一定會(huì)發(fā)現(xiàn)下愈,這不就是上面的方法嗎纽绍,若說(shuō)區(qū)別就是一個(gè)傳遞了所要返回的Activity對(duì)應(yīng)的class這個(gè)參數(shù)蕾久,并調(diào)用了backTo(targetActivity),另一個(gè)是直接finish的拌夏∩或許可以做個(gè)判斷如果傳入的targetActivity為null則調(diào)用finish豈不是更好,何必重載一遍方法障簿。以上的方法自然可以的盹愚,至于是否使用則需要看我們所開發(fā)的項(xiàng)目有多復(fù)雜。 不過(guò)從我封裝BaseActivity的角度出發(fā)站故,關(guān)閉當(dāng)前的Activity使用的卻不是上面的這個(gè)方法皆怕,而是重載了下面的三個(gè)方法:
1.在使用的時(shí)候,考慮都方法或者控件的復(fù)用效果西篓,雖然我們的設(shè)計(jì)初衷是“關(guān)閉按鈕”愈腾,可是真正的開發(fā)過(guò)程中,誰(shuí)也不知道產(chǎn)品會(huì)開個(gè)什么腦洞岂津。而且即便不是產(chǎn)品故意為難我們虱黄,有一些頁(yè)面在關(guān)閉的時(shí)候,難免要求彈窗提示用戶“是否放棄當(dāng)前頁(yè)面的操作”吮成,所以點(diǎn)擊事件就不是一成不變的了橱乱,所以這里添加了一個(gè)boolean值,去做這個(gè)判斷粱甫。也就是說(shuō)泳叠,當(dāng)我們需要重置點(diǎn)擊事件的時(shí)候傳入true即可,而不需要重置的時(shí)候茶宵,則傳入false危纫,就會(huì)調(diào)用finish方法了。
/**
* 設(shè)置關(guān)閉點(diǎn)擊事件
*
* @param isResetClose 是否重置關(guān)閉按鈕點(diǎn)擊事件
*/
public void setBaseClose(boolean isResetClose) {
initBaseView();
baseClose = getView(R.id.base_close);
if (isResetClose) {
baseClose.setOnClickListener(this);
} else {
baseClose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
}
}
baseClose.setOnClickListener(this);是因?yàn)锽aseActivity是實(shí)現(xiàn)了View.OnClickListener的抽象類 2.當(dāng)前的重載方法同樣是從重載的角度出發(fā)的,因?yàn)辄c(diǎn)擊事件如果被重新定義的話叶摄,圖標(biāo)也可能會(huì)有所改變属韧,這里只需要將對(duì)應(yīng)圖標(biāo)的資源id傳來(lái)即可。當(dāng)然蛤吓,既然重新設(shè)置圖標(biāo)宵喂,我就當(dāng)你肯定會(huì)重新定義點(diǎn)擊事件了,大家如果想完善個(gè)只換圖標(biāo)会傲,點(diǎn)擊事件不變的锅棕,可以自行添加(如果整個(gè)項(xiàng)目都統(tǒng)一換,請(qǐng)直接替換默認(rèn)圖片資源)淌山。
/**
* 設(shè)置關(guān)閉點(diǎn)擊事件
*
* @param resId 重置關(guān)閉按鈕圖標(biāo)
*/
public void setBaseClose(int resId) {
initBaseView();
baseClose = getView(R.id.base_close);
baseClose.setImageResource(resId);
baseClose.setOnClickListener(this);
}
3.不過(guò)當(dāng)下單純的使用關(guān)閉按鈕的情況比較多裸燎,所以這里添加了一個(gè)重載方法,一般而言泼疑,我們直接調(diào)用這個(gè)方法即可德绿,畢竟對(duì)于我這種懶漢來(lái)說(shuō),多寫個(gè)false還是很麻煩的退渗。
/**
* 設(shè)置關(guān)閉點(diǎn)擊事件
*/
public void setBaseClose() {
setBaseClose(false);
}
或許有人會(huì)問(wèn)移稳,為什么批量關(guān)閉Activity的方法就沒有這么多情況分析,難倒批量關(guān)閉Activity的時(shí)候就不存在自定義嗎会油?答案自然是有的个粱。至于為什么沒有分析,難倒調(diào)用setBaseClose(true);不能重新定義批量關(guān)閉Activity的點(diǎn)擊事件嗎翻翩?
其實(shí)上述的方法就已經(jīng)很全面了都许,不過(guò)下面這段也不算是狗尾續(xù)貂吧,只能說(shuō)是被產(chǎn)品摧殘多了以后的一種自覺的反應(yīng):
/**
* 隱藏關(guān)閉按鈕
*/
public void hideBaseClose() {
if (null != baseClose){
baseClose.setVisibility(View.GONE);
} else {
Logger.e(getName(),"baseClose is not exist");
}
}
/**
* 顯示關(guān)閉按鈕
*/
public void showBaseClose() {
if (null != baseClose){
baseClose.setVisibility(View.VISIBLE);
} else {
Logger.e(getName(),"baseClose is not exist");
}
}
上面兩個(gè)方法分別是關(guān)閉按鈕的隱藏和顯示方法嫂冻,是在為了動(dòng)態(tài)處理關(guān)閉按鈕而添加的胶征,一般情況下也使用不到,除非是產(chǎn)品說(shuō):當(dāng)WebView中絮吵,剛進(jìn)入H5頁(yè)面時(shí)不需要顯示關(guān)閉按鈕弧烤,當(dāng)經(jīng)過(guò)操作,重新返回到首頁(yè)時(shí)蹬敲,由于返回鍵與關(guān)閉鍵功能重復(fù)暇昂,需要將關(guān)閉鍵隱藏的時(shí)候。至于為什么在baseClose不存在的時(shí)候伴嗡,只是報(bào)錯(cuò)(Logger是我封裝的Log)而沒做其他法處理急波,實(shí)在是控件為空的原因,還需要特殊提醒嗎瘪校?
title設(shè)置
翻譯過(guò)來(lái)就是我們想要查找的資源不存在卡啰,而這個(gè)資源是什么呢静稻?
private int count = 0;
@SuppressLint("SetTextI18n")
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.merge_btn:
view.setText(count++);
break;
}
}
也就是說(shuō),當(dāng)我們?cè)O(shè)置的參數(shù)為數(shù)字的時(shí)候匈辱,這個(gè)數(shù)字會(huì)自動(dòng)被當(dāng)做資源id振湾,所以說(shuō),在設(shè)置數(shù)字的時(shí)候亡脸,我們都需要將數(shù)字轉(zhuǎn)換為字符串才能正常顯示押搪。不過(guò),正是因?yàn)檫@個(gè)梗掰,所以上面我設(shè)置的“MyTitle”的時(shí)候嵌言,可以有兩種方式:
// 字符串
title.setText("MyTitle");
<resources>
<string name="title">MyTitle</string>
...
</resources>
<--資源id 在res-->values-->strings.xml文件中-->
// 資源id
title.setText(R.string.title);
所以這里封裝的setTitle方法也是有兩部分:
/**
* 設(shè)置標(biāo)題
*
* @param title 標(biāo)題的文本
*/
public void setTitle(String title) {
initBaseView();
((TextView) getView(R.id.base_title)).setText(title);
}
/**
* 設(shè)置標(biāo)題
*
* @param titleId 標(biāo)題的文本
*/
public void setTitle(int titleId) {
initBaseView();
((TextView) getView(R.id.base_title)).setText(titleId);
}
返回鍵
返回鍵基本上是title的標(biāo)配了,使用不到返回鍵的地方基本也就是首頁(yè)罷了(啟動(dòng)頁(yè)及穗、引導(dǎo)頁(yè)、登錄頁(yè)等頁(yè)面不需要返回鍵的同時(shí)绵载,也不需要title)埂陆,所以這里返回鍵的初始化的部分就不單獨(dú)列舉方法了,而是與上面的setTitle融合在了一起娃豹,添加一個(gè)boolean值焚虱,用于設(shè)置是否需要展示返回鍵。
/**
* 設(shè)置標(biāo)題
*
* @param title 標(biāo)題的文本
* @param showBack 是否顯示返回鍵
*/
public void setTitle(String title, boolean showBack) {
initBaseView();
((TextView) getView(R.id.base_title)).setText(title);
if (showBack) {
baseBack = getView(R.id.base_back);
baseBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}
/**
* 設(shè)置標(biāo)題
*
* @param titleId 標(biāo)題的文本
* @param showBack 是否顯示返回鍵(一般只用于首頁(yè))
*/
public void setTitle(int titleId, boolean showBack) {
initBaseView();
((TextView) getView(R.id.base_title)).setText(titleId);
if (showBack) {
baseBack = getView(R.id.base_back);
baseBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}
當(dāng)然懂版,由于不顯示返回鍵的情況過(guò)少鹃栽,所以這里在外層又封裝了兩個(gè)方法,至于原因躯畴,自然是多寫個(gè)true麻煩嘍:
/**
* 設(shè)置標(biāo)題
*
* @param title 標(biāo)題的文本
*/
public void setTitle(String title) {
setTitle(title, true);
}
/**
* 設(shè)置標(biāo)題
*
* @param titleId 標(biāo)題的文本
*/
public void setTitle(int titleId) {
setTitle(titleId, true);
}
除此之外民鼓,返回鍵的圖標(biāo)也可能會(huì)做出修改,所以也定義了修改的方法:
/**
* 重置返回點(diǎn)擊事件
*
* @param resId 重置返回按鈕圖標(biāo)
*/
public void setBaseBack(int resId) {
initBaseView();
baseBack = getView(R.id.base_back);
baseBack.setImageResource(resId);
baseBack.setOnClickListener(this);
}
再往復(fù)雜了考慮蓬抄,就是在使用的時(shí)候丰嘉,我們之前使用的時(shí)候是直接返回,可當(dāng)滿足一定條件嚷缭,會(huì)重置返回鍵饮亏,這里也添加了重置的方法:
/**
* 重置返回點(diǎn)擊事件
*/
public void resetBaseBack() {
if (null != baseBack) {
baseBack.setOnClickListener(this);
} else {
Logger.e(getName(), "baseBack is not exist!");
}
}
右側(cè)功能鍵
這部分耍贾,在之前的博客《一個(gè)Android工程的從零開始》-2、base(一) BaseActivity布局中有所介紹路幸,而本次也沒有做出太多調(diào)整具體的可以去這篇博客中看荐开,這里就只貼出代碼效果圖,以及對(duì)調(diào)整的地方做出說(shuō)明了简肴,先是在前面的布局優(yōu)化博客中截出的效果圖:
實(shí)現(xiàn)的方法如下:
/**
* 最右側(cè)圖片功能鍵設(shè)置方法
*
* @param resId 圖片id
* @param alertText 語(yǔ)音輔助提示讀取信息
* @return 將當(dāng)前ImageView返回方便進(jìn)一步處理
*/
public ImageView setBaseRightIcon1(int resId, String alertText) {
initBaseView();
baseRightIcon1 = getView(R.id.base_right_icon1);
baseRightIcon1.setImageResource(resId);
baseRightIcon1.setVisibility(View.VISIBLE);
//語(yǔ)音輔助提示的時(shí)候讀取的信息
baseRightIcon1.setContentDescription(alertText);
baseRightIcon1.setOnClickListener(this);
return baseRightIcon1;
}
/**
* 右數(shù)第二個(gè)圖片功能鍵設(shè)置方法
*
* @param resId 圖片id
* @param alertText 語(yǔ)音輔助提示讀取信息
* @return 將當(dāng)前ImageView返回方便進(jìn)一步處理
*/
public ImageView setBaseRightIcon2(int resId, String alertText) {
ImageView baseRightIcon2 = getView(R.id.base_right_icon2);
if (null != baseRightIcon1) {
baseRightIcon2.setImageResource(resId);
baseRightIcon2.setVisibility(View.VISIBLE);
//語(yǔ)音輔助提示的時(shí)候讀取的信息
baseRightIcon2.setContentDescription(alertText);
baseRightIcon2.setOnClickListener(this);
} else {
Logger.e(getName(),"You must inflate the baseRightIcon1 before use baseRigh
}
return baseRightIcon2;
}
/**
* 最右側(cè)文本功能鍵設(shè)置方法
*
* @param text 文本信息
* @return 將當(dāng)前TextView返回方便進(jìn)一步處理
*/
public TextView setBaseRightText(String text) {
initBaseView();
TextView baseRightText = getView(R.id.base_right_text);
baseRightText.setText(text);
baseRightText.setVisibility(View.VISIBLE);
baseRightText.setOnClickListener(this);
return baseRightText;
}
/**
* 最右側(cè)文本功能鍵設(shè)置方法
*
* @param textId 文本信息id
* @return 將當(dāng)前TextView返回方便進(jìn)一步處理
*/
public TextView setBaseRightText(int textId) {
initBaseView();
TextView baseRightText = getView(R.id.base_right_text);
baseRightText.setText(textId);
baseRightText.setVisibility(View.VISIBLE);
baseRightText.setOnClickListener(this);
return baseRightText;
}
這里與之前不同的地方只有setBaseRightIcon2誓焦,因?yàn)樵诓季种校邢聢D所示的關(guān)系: 也就是說(shuō)着帽,BaseRightIcon2需要在BaseRightIcon1的基礎(chǔ)上確定位置杂伟,所以在沒有調(diào)用setBaseRightIcon1便直接調(diào)用setBaseRightIcon2給出錯(cuò)誤提示。
其他
其他還有兩個(gè)方法:
/**
* 隱藏頭布局
*/
public void hideTitle() {
if (titleStub != null) {
titleStub.setVisibility(View.GONE);
}
}
/**
* 隱藏返回鍵
*/
public void hideBack() {
if (null != baseBack) {
baseBack.setVisibility(View.GONE);
} else {
Logger.e(getName(), "baseBack is not exist!");
}
}
這兩個(gè)方法是之前使用include添加布局的時(shí)候使用的方法仍翰,一般邏輯下赫粥,用不到上面兩個(gè)方法,不過(guò)暫時(shí)沒有刪除予借,后期看情況處理越平。