先扯兩句
今天進入BaseActivity的第三部分——Title,這名字取的就順嘴多了,想必大家從名字上也能看出來說的是什么,就不需要解釋了,(雖然不想承認,其實是因為我懶),那么開始今天的內容吧。
還是想把我的碼云地址分享給大家:
[基于ConstraintLayout的]
(https://git.oschina.net/bsw_lm/ConstraintLayoutBaseApplication)[未使用ConstraintLayout的]
(https://git.oschina.net/bsw_lm/MyBaseApplication)
正文
想必有一部分人看完昨天的部分,會有一些疑問,那就是雖然經過昨天的內容,我們能夠用Activity繼承BaseActivity,并將對應的布局文件,顯示到BaseActivity的title的下方,看起來卻是省事了許多,可是title卻是死的,如何去更改文本,控制按鈕顯示,或者說還有一些APP的首頁,是不需要顯示title的,這部分又如何操作呢。
下面就正是進入這部分,具體的也不亂說了,直接上方法。
設置標題:###
/**
* 設置標題
* @param title 標題的文本
*/
public void setTitle(String title) {
TextView baseTitle = (TextView) findViewById(R.id.base_title);
baseTitle.setText(title);
}
還是綁定控件,然后設置標題,而標題的文本,則是通過方法傳來的。
調用與上一篇中所說的類似,首先繼承BaseActivity,然后調用setTitle方法,并寫入參數即可。
代碼如下:
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setBaseContentView(R.layout.activity_main);
setTitle("新Title");
}
}
下面我們來看一下效果:
這張是原本的默認title的情況下:
設置了之后的效果:
這樣就完成了Title的動態設置了。
返回按鍵###
下面我們再來看看左側的返回鍵功能如何完成,其實這部分比title還要簡單一些,因為這部分只需要在BaseActivity中做處理就可以了。
具體方法大家肯定都知道,先是在BaseActivity實現View.OnClickListener接口,在重寫的onClick做id匹配,找到當點擊的是返回時,調用finish(),代碼如下(實現接口的部分想必大家都知道,就不貼了):
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.base_back:
finish();
break;
default:
break;
}
}
完成以上操作就可以實現退出了。
當然,也不是每一次我們都需要他點擊了退出就立刻推掉的,例如編輯日記等,點擊退出的時候,就需要做一個“是否放棄編輯”的提示,所以就需要額外加一些處理。
首先在BaseActivity中添加如下方法。
public ImageView getBaseBack() {
return (ImageView) findViewById(R.id.base_back);
}
再回到MainActivity的onCreate方法中,添加如下代碼:
getBaseBack().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("log","退不出去了吧");
}
});
這時再點擊返回鍵的時候,就不會退出了,而是會在as的logcat面板中打印出“退不出去了吧”。而你想做什么操作,只要替換掉Log.i("log","退不出去了吧");,寫自己的代碼就好。
當然,或許會有人有疑惑,為什么這里需要重新new一個OnClickListener,BaseActivity已經實現了,那我們直接用getBaseBack().setOnClickListener(this);不就可以了嗎?
這種方法我自然也嘗試過,具體想了解的可以參見附錄1。
當然,首頁也有一些不需要返回鍵的,所以也單獨寫了一個方法,用來隱藏返回鍵。
/**
* 隱藏返回鍵
*/
private void hideBack() {
baseBack.setVisibility(View.GONE);
}
功能按鍵###
除了以上這兩種以外,title中余下的標題或者是文字我就統稱為功能按鍵了。對于這些功能按鍵呢,我們需要的處理肯定更復雜,至于為什么,如果簡單肯定不會放在最后說啊。
第一點:
相信分析一下,也確實如此,雖然我在第二篇博客中開始布局的時候,都使用了對應的圖片,可是大家使用APP的時候肯定發現了,文字肯定不止是“確定”兩個字,圖片自然也不可能永遠都是加號和更多(也就是橫著排列的三個點)。
第二點:
再就是既然是按鍵,肯定也需要做點擊事件,而且在不同的圖片、不同的頁面以及當前頁面不同的狀態,每個位置上的按鍵,所對應的點擊事件也會不完全相同,所以按鍵的功能也需要我們做一下處理。
第三點:
也是在第二篇博客中,我就已經分析了這幾個功能鍵可能出現的幾種情況,什么都不顯示啊、顯示一個功能鍵啊、顯示兩個功能鍵。而對應每種情況,我們必然要設置誰顯示,誰隱藏。
我重新縷清一下順序,總結一下所需要處理的三個點(順序有所調整)。
- 顯隱
- 文本或者圖片資源的切換
- 點擊事件
分析好了,我們一個一個的來:
顯隱
這部分最為簡單,那就是將所有的功能控件的visibility都設置成gone,當需要調用哪個的時候,用java代碼設置成View.VISIBLE就可以實現。
文本或者圖片資源的切換
這部分內容呢,其實也比較簡單,文本的就不用說了,參考一下title文本的設置部分即可,我們主要說一下圖片(當然,主要說圖片的主要原因還是因為圖片的前面沒有說罷了)。
這里所用的都是存在res目錄下的圖片資源,至于網絡動態獲取的部分,后面說到的時候,大家拿來用即可。
取id比較簡單:
R.mipmap.more
就是res目錄下的mipmap目錄下的more圖片,當然也有用drawable文件夾的(兩個文件夾的區別我前面說過了,這里就不重復了)。
設置給ImageView設置圖片的,好吧,也不復雜:
baseRightIcon1.setImageResource(resId);
baseRightIcon1就是ImageView,resId是傳來的圖片Id,所以這部分也搞定了。
點擊事件
這里呢,其實也只需要兩個部分:
一、設置點擊監聽,這個部分在BaseActivity的方法中完成
baseRightIcon1.setOnClickListener(this);
二、設置點擊事件,這個部分在MainActivity(也就是要實現點擊的活動類)中完成
@Override
public void onClick(View v) {
super.onClick(v);
switch (v.getId()) {
case R.id.base_right_icon1:
Log.i("Exception", "你點到我了");
break;
default:
break;
}
}
下面貼出來完整的方法:
BaseActivity中的設置方法,
/**
* 設置右側圖片1(最右側)
*
* @param resId 圖片的資源id
* @param alertText 提示文本
*/
public void setBaseRightIcon1(int resId, String alertText) {
baseRightIcon1.setImageResource(resId);
baseRightIcon1.setVisibility(View.VISIBLE);
baseRightIcon1.setOnClickListener(this);
//語音輔助提示的時候讀取的信息
baseRightIcon1.setContentDescription(alertText);
}
MainActivity中的調用(在OnCreate中):
setBaseRightIcon1(R.mipmap.more, "更多");
好了以上就是今天的內容了嗎?嗯,你個人勤快些的話,到這里就可以了,可是我這個人就是出奇的懶,每次都需要重寫OnClick方法,而且還需要去記這幾個功能鍵的id,別人我不知道,反正我個人是怕麻煩,所以想到了一個偷懶的方法。
接口的使用
看到題目想必大家也知道了,這部分要使用的內容就是接口了,不知大家是什么狀態,反正我學java的時間內,最學不明白的就是接口,如今能把接口運用上,并且寫到博客里,還是很有成就感的。
其實使用接口,我也比較無奈,實在是java不能像JavaScript一樣,直接把方法做參數傳遞,不然又何必這么費事。接口的定義我就不多說了,畢竟從小就比較討厭這些中看不中用的東西,我就直接上代碼了。
在BaseActivity中做如下操作:
首先創建如下接口:
public interface OnClickRightIcon1CallBack {
void clickRightIcon1();
}
里面就一個方法,因為接口中的方法會默認抽象,所以我就偷懶沒有寫。
隨后創建一個私有的OnClickRightIcon1:
private OnClickRightIcon1CallBack onClickRightIcon1;
修改前面使用到的setBaseRightIcon1方法,添加一個參數OnClickRightIcon1CallBack onClickRightIcon1,并在其中添加一行代碼:
this.onClickRightIcon1 = onClickRightIcon1;
修改后的setBaseRightIcon1長成這個樣
/**
* 設置右側圖片1(最右側)
*
* @param resId 圖片的資源id
* @param alertText 提示文本
* @param onClickRightIcon1 點擊處理接口
*/
public void setBaseRightIcon1(int resId, String alertText, OnClickRightIcon1CallBack onClickRightIcon1) {
this.onClickRightIcon1 = onClickRightIcon1;
baseRightIcon1.setImageResource(resId);
baseRightIcon1.setVisibility(View.VISIBLE);
baseRightIcon1.setOnClickListener(this);
//語音輔助提示的時候讀取的信息
baseRightIcon1.setContentDescription(alertText);
}
最后一步,在OnClick中添加對應的id,并做點擊處理。
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.base_back:
finish();
break;
case R.id.base_right_icon1:
onClickRightIcon1.clickRightIcon1();
break;
default:
break;
}
}
如此操作下來,在子類中調用接口,就能點擊操作了:
setBaseRightIcon1(R.mipmap.more, "更多", new OnClickRightIcon1CallBack() {
@Override
public void clickRightIcon1() {
Log.i("Exception","這都找到我了");
}
});
完整代碼參見附錄2
附錄
附錄1
我們如果按照設想的樣子,直接用getBaseBack().setOnClickListener(this);,此時如果我們在MainActivity中重寫OnClick方法處理返回事件的時候就會變成這個樣子:
@Override
public void onClick(View v) {
super.onClick(v);
switch (v.getId()) {
case R.id.base_back:
Log.i("log","退不出去了吧");
break;
default:
break;
}
}
執行的結果,你當然也可以看到“退不出去了吧”的輸出日志,可是同樣你也會看到當前的Activity關閉了。
這是為什么呢,細心的會發現,這段代碼多出了super.onClick(v);,也就是說在執行重新寫的OnClick之前,需要先執行BaseActivity中的OnClick,所以自然就會兩部分都執行到了。
當然或許還會有人說,那么既然找到問題了,我們注釋掉super.onClick(v);不就可以了嗎?
這樣做自然是可以的,但是這里有一個前提,那就是我們BaseActivity的OnClick方法中不會有其他的點擊事件處理,不然你注釋掉這行代碼后,其他的那些點擊事件也不會有反應了。除非你能把使用到的每一個都重寫。
還有一個點,就是每當你需要處理返回按鈕的時候,都要想著將這行代碼注釋掉,不然就等著跟領導聊天吧。
所以如此的話,還不如簡簡單單重新new一個OnClickListener來得方便。
附錄2
BaseActivity####
package com.mybaseapplication.base;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import com.mybaseapplication.R;
import butterknife.ButterKnife;
public class BaseActivity extends AppCompatActivity implements View.OnClickListener {
public Activity context;
private ImageView baseBack, baseRightIcon2, baseRightIcon1;
private TextView baseTitle, baseRightText;
private OnClickRightIcon1CallBack onClickRightIcon1;
private OnClickRightIcon2CallBack onClickRightIcon2;
private OnClickRightTextCallBack onClickRightText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
ButterKnife.inject(this);
context = this;
initView();
}
/**
* 隱藏返回鍵
*/
private void hideBack() {
baseBack.setVisibility(View.GONE);
}
/**
* 獲取返回鍵
*/
public ImageView getBackImage() {
return baseBack;
}
/**
* 初始化控件
*/
private void initView() {
baseRightIcon1 = (ImageView) findViewById(R.id.base_right_icon1);
baseRightIcon2 = (ImageView) findViewById(R.id.base_right_icon2);
baseBack = (ImageView) findViewById(R.id.base_back);
baseTitle = (TextView) findViewById(R.id.base_title);
baseRightText = (TextView) findViewById(R.id.base_right_text);
baseBack.setOnClickListener(this);
}
/**
* 設置標題
*
* @param title 標題的文本
*/
public void setTitle(String title) {
baseTitle.setText(title);
}
/**
* 設置右側圖片1(最右側)
*
* @param resId 圖片的資源id
* @param alertText 提示文本
* @param onClickRightIcon1 點擊處理接口
*/
public void setBaseRightIcon1(int resId, String alertText, OnClickRightIcon1CallBack onClickRightIcon1) {
this.onClickRightIcon1 = onClickRightIcon1;
baseRightIcon1.setImageResource(resId);
baseRightIcon1.setVisibility(View.VISIBLE);
baseRightIcon1.setOnClickListener(this);
//語音輔助提示的時候讀取的信息
baseRightIcon1.setContentDescription(alertText);
}
/**
* 設置右側圖片2(右數第二個圖片)
*
* @param resId 圖片的資源id
* @param alertText 提示文本
*/
public void setBaseRightIcon2(int resId, String alertText, OnClickRightIcon2CallBack onClickRightIcon2) {
this.onClickRightIcon2 = onClickRightIcon2;
baseRightIcon2.setImageResource(resId);
baseRightIcon2.setVisibility(View.VISIBLE);
baseRightIcon2.setOnClickListener(this);
//語音輔助提示的時候讀取的信息
baseRightIcon2.setContentDescription(alertText);
}
/**
* 設置右側文本信息
*
* @param text 所需要設置的文本
*/
public void setBaseRightText(String text, OnClickRightTextCallBack onClickRightText) {
this.onClickRightText = onClickRightText;
baseRightText.setText(text);
baseRightText.setVisibility(View.VISIBLE);
baseRightText.setOnClickListener(this);
}
/**
* 引用頭部布局
*
* @param layoutId 布局id
*/
public void setBaseContentView(int layoutId) {
//當子布局高度值不足ScrollView時,用這個方法可以充滿ScrollView,防止布局無法顯示
((ScrollView) findViewById(R.id.base_scroll_view)).setFillViewport(true);
LinearLayout layout = (LinearLayout) findViewById(R.id.base_main_layout);
//獲取布局,并在BaseActivity基礎上顯示
final View view = getLayoutInflater().inflate(layoutId, null);
//關閉鍵盤
hideKeyBoard();
//給EditText的父控件設置焦點,防止鍵盤自動彈出
view.setFocusable(true);
view.setFocusableInTouchMode(true);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
layout.addView(view, params);
}
/**
* 隱藏鍵盤
*/
public void hideKeyBoard() {
View view = ((Activity) context).getWindow().peekDecorView();
if (view != null) {
InputMethodManager inputmanger = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
inputmanger.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//返回按鍵
case R.id.base_back:
finish();
break;
//圖片1
case R.id.base_right_icon1:
onClickRightIcon1.clickRightIcon1();
break;
//圖片2
case R.id.base_right_icon2:
onClickRightIcon2.clickRightIcon2();
break;
//右側文本
case R.id.base_right_text:
onClickRightText.clickRightText();
break;
default:
break;
}
}
/**
* 圖片一點擊回調接口
*/
public interface OnClickRightIcon1CallBack {
void clickRightIcon1();
}
public interface OnClickRightIcon2CallBack {
void clickRightIcon2();
}
public interface OnClickRightTextCallBack {
void clickRightText();
}
}
MainActivity####
package com.mybaseapplication.ui.activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.mybaseapplication.R;
import com.mybaseapplication.base.BaseActivity;
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setBaseContentView(R.layout.activity_main);
//設置title文本
setTitle("新Title");
//設置返回攔截
getBaseBack().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("log","退不出去了吧");
}
});
//設置功能鍵,以及點擊方法回調監聽
setBaseRightIcon1(R.mipmap.more, "更多", new OnClickRightIcon1CallBack() {
@Override
public void clickRightIcon1() {
Log.i("Exception","這都找到我了");
}
});
}
}