如果是只有一个Activity的App就没有必要写BaseActivity,但一旦大于一个我还是建议写一个BaseActivity,准没错。
每个Activity通常都是绑定视图,绑定控件,监听控件,获取Bundle,跳转Activity还有一些很有些烦人的小功能如:Toast,findViewById,我们都可以封装一层简化他们的使用
BaseActivity的代码如下:
/**
* Author : 马占柱
* E-mail : mazhanzhu_3351@163.com
* Time : 2019/11/29 15:49
* Desc : BaseActivity
*/
public abstract class BaseActivity_Impl extends AppCompatActivity implements View.OnClickListener {
protected final String TAG = this.getClass().getSimpleName();//日志输出标志
private boolean isSetStatusBar = true;//是否沉浸状态栏:即 不显示状态栏 【默认不设置】
private boolean mAllowFullScreen = true;//是否允许全屏【默认全屏】
private int netMobile;//网络类型
protected Activity context;
protected boolean mNetConnect;
protected boolean isMzz = true;//网络请求标识
private PassengerLoading progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= 28) {//适配挖孔屏全屏显示
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
getWindow().setAttributes(lp);
}
context = this;
Bundle bundle = getIntent().getExtras();
initParms(bundle);//注意此处的位置
if (mAllowFullScreen) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
}
if (isSetStatusBar) {
steepStatusBar();
}
setColorStatus(true);
setContentView(bindLayout());// 注意这里的位置;要在“requestWindowFeature”之后
ButterKnife.bind(this);
ActivityManager_Singe.getInstance().addActivity(context);
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);// 禁止手机进行截图操作
//注册eventbus
if (isRegisterEventBus()) {
EventBusUtils.register(this);
}
mNetConnect = inspectNet();
//这个放到最后
initView(savedInstanceState);
// OpenGray(true);//测试,全部页面变灰
}
/**
* [初始化参数]
* 解析bundle内容或者设置是否旋转,沉浸,全屏
*/
public abstract void initParms(Bundle parms);
/**
* [沉浸状态栏+透明效果]
*/
private void steepStatusBar() {
View decorView = getWindow().getDecorView();
// 此时使用 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 时界面会和导航栏重叠
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
getWindow().setStatusBarColor(Color.TRANSPARENT);
// 透明状态栏
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// 透明导航栏
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
try {
//保持屏幕常亮
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
@SuppressLint("InvalidWakeLockTag") PowerManager.WakeLock mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "WakeLock");
mWakeLock.acquire();
} catch (Exception e) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
/**
* @param isLightMode true 标题栏黑色 false 白色
*/
protected void setColorStatus(boolean isLightMode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Window window = context.getWindow();
int option = window.getDecorView().getSystemUiVisibility();
if (isLightMode) {
option |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
} else {
option &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
window.getDecorView().setSystemUiVisibility(option);
}
}
/**
* [绑定布局]
*/
public abstract int bindLayout();
/**
* [初始化控件]
*/
public abstract void initView(Bundle savedInstanceState);
@Override
public void onClick(View v) {
if (AppUtils.isFastClick()) return;
click(v);
}
/**
* 点击事件
*/
public abstract void click(View v);
/**
* [绑定控件]
*/
protected <T extends View> T $(int resId) {
return (T) super.findViewById(resId);
}
/**
* [页面跳转]
*/
public void startActivity(Class<?> clz) {
startActivity(new Intent(BaseActivity_Impl.this, clz));
}
/**
* [携带数据的页面跳转]
*/
public void startActivity(Class<?> clz, Bundle bundle) {
Intent intent = new Intent();
intent.setClass(this, clz);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivity(intent);
}
/**
* [含有Bundle通过Class打开编辑界面]
*/
public void startActivityForResult(Class<?> cls, Bundle bundle, int requestCode) {
Intent intent = new Intent();
intent.setClass(this, cls);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivityForResult(intent, requestCode);
}
//点击外部隐藏键盘
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if (isShouldHideInput(v, ev)) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
return super.dispatchTouchEvent(ev);
}
// 必不可少,否则所有的组件都不会有TouchEvent了
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
public boolean isShouldHideInput(View v, MotionEvent event) {
if (v != null && (v instanceof EditText)) {
int[] leftTop = {0, 0};
//获取输入框当前的location位置
v.getLocationInWindow(leftTop);
int left = leftTop[0];
int top = leftTop[1];
int bottom = top + v.getHeight();
int right = left + 100000;
if ((event.getX() > left) && (event.getX() < right) && (event.getY() > top) && (event.getY() < bottom)) {
// 点击的是输入框区域,保留点击EditText的事件
return false;
} else {
return true;
}
}
return false;
}
/**
* 是否允许全屏
* <p>
* 默认true—全屏
*
* @param allowFullScreen true—全屏;false—非全屏
*/
public void setAllowFullScreen(boolean allowFullScreen) {
this.mAllowFullScreen = allowFullScreen;
}
/**
* 是否设置沉浸状态栏]
*/
public void setSteepStatusBar(boolean isSetStatusBar) {
this.isSetStatusBar = isSetStatusBar;
}
/**
* 初始化时判断有没有网络
*/
public boolean inspectNet() {
this.netMobile = NetUtil.getNetWorkState(context);
return isNetConnect();
}
/**
* 判断有无网络
*
* @return true 有网, false 没有网络.
*/
protected boolean isNetConnect() {
if (netMobile == NetUtil.NETWORK_WIFI) {
return true;
} else if (netMobile == NetUtil.NETWORK_MOBILE) {
return true;
} else if (netMobile == NetUtil.NETWORK_NONE) {
return false;
}
return false;
}
/**
* @param title 标题
* @param isshow 右侧是否显示 【true 显示,false 不显示】
*/
public void setActionBar(String title, boolean isshow) {
RelativeLayout ll_car_back = context.findViewById(R.id.ll_car_back);
TextView main_tabra_title = context.findViewById(R.id.tv_center_title);
LinearLayout ll_verify_history = context.findViewById(R.id.ll_verify_history);
ll_car_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityManager_Singe.getInstance().finishActivity(context);
}
});
main_tabra_title.setText(title);
if (isshow) {
ll_verify_history.setVisibility(View.VISIBLE);
} else {
ll_verify_history.setVisibility(View.INVISIBLE);
}
}
/**
* 设置是否显示标题下面的分割线
*
* @param b 默认显示
*/
public void setVisibleView(boolean b) {
View title_view = context.findViewById(R.id.title_view);
title_view.setVisibility(b ? View.VISIBLE : View.GONE);
}
/**
* @param title 标题
* @param isshow 右侧是否显示 【true 显示,false 不显示】
* @param img 右侧图片是否显示 【true 显示,false 不显示】
*/
public void setActionBar(String title, boolean isshow, boolean img, final Click_Ma ma) {
RelativeLayout ll_car_back = context.findViewById(R.id.ll_car_back);
TextView main_tabra_title = context.findViewById(R.id.tv_center_title);
ImageView bar_right_img = context.findViewById(R.id.bar_right_img);
TextView bar_right_txt = context.findViewById(R.id.bar_right_txt);
LinearLayout ll_verify_history = context.findViewById(R.id.ll_verify_history);
ll_car_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!AppUtils.isFastClick())
ActivityManager_Singe.getInstance().finishActivity(context);
}
});
main_tabra_title.setText(title);
if (isshow) {
bar_right_img.setVisibility(img ? View.VISIBLE : View.GONE);
bar_right_txt.setVisibility(img ? View.GONE : View.VISIBLE);
ll_verify_history.setVisibility(View.VISIBLE);
} else {
ll_verify_history.setVisibility(View.INVISIBLE);
}
ll_verify_history.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!AppUtils.isFastClick()) ma.onclick();
}
});
}
/**
* Create by Mazhanzhu on 2019/9/18
*/
public interface Click_Ma {
/**
* 点击事件
*/
void onclick();
}
/**
* 处理eventbus发过来的事件
*/
@Subscribe(threadMode = ThreadMode.MAIN)
public void handleMessage(EventBus_Message baseEvent) {
}
/**
* 是否注册事件分发
*
* @return true绑定EventBus事件分发,默认不绑定,子类需要绑定的话复写此方法返回true.
*/
protected boolean isRegisterEventBus() {
return false;
}
/**
* 检查当前系统是否已开启暗黑模式
*/
public static boolean getDarkModeStatus(Context context) {
int mode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
return mode == Configuration.UI_MODE_NIGHT_YES;
}
/**
* 是否设置灰度值
*/
private void OpenGray(boolean isOpen) {
if (isOpen) {
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
//设置 0 为灰度模式
cm.setSaturation(0);
paint.setColorFilter(new ColorMatrixColorFilter(cm));
getWindow().getDecorView().setLayerType(View.LAYER_TYPE_HARDWARE, paint);
} else {
getWindow().getDecorView().setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
}
public void showLoading(boolean show) {
if (show) {
if (progressDialog == null) {
progressDialog = new PassengerLoading(context);
}
if (!progressDialog.isShowing()) {
progressDialog.show();
}
} else {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
}
public View getEmpty_Data() {
View emptyView = View.inflate(context, R.layout.emptyview, null);
ImageView empty_img = emptyView.findViewById(R.id.empty_img);
empty_img.setBackgroundResource(R.mipmap.empty_data);
emptyView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
return emptyView;
}
public View getEmpty_Search() {
View emptyView = View.inflate(context, R.layout.emptyview, null);
ImageView empty_img = emptyView.findViewById(R.id.empty_img);
empty_img.setBackgroundResource(R.mipmap.empty_search);
emptyView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
return emptyView;
}
/**
* 设置EditText只能输入小数点后两位,在价格等有限制的输入时特别有效
*/
protected void setEditChanged(EditText editText) {
editText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.toString().contains(".")) {
if (s.length() - 1 - s.toString().indexOf(".") > 2) {
s = s.toString().subSequence(0, s.toString().indexOf(".") + 3);
editText.setText(s);
editText.setSelection(s.length());
}
}
if (s.toString().trim().equals(".")) {
s = "0" + s;
editText.setText(s);
editText.setSelection(2);
}
if (s.toString().startsWith("0") && s.toString().trim().length() > 1) {
if (!s.toString().substring(1, 2).equals(".")) {
editText.setText(s.subSequence(0, 1));
editText.setSelection(1);
}
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
/**
* 编辑框禁用emoji表情和颜文字
*/
protected void setEditEmoji(EditText editText) {
InputFilter inputFilter = new InputFilter() {
Pattern pattern = Pattern.compile("[^a-zA-Z0-9\u4E00-\u9FA5]");
@Override
public CharSequence filter(CharSequence charSequence, int i, int i1, Spanned spanned, int i2, int i3) {
Matcher matcher = pattern.matcher(charSequence);
if (!matcher.find()) {
return null;
} else {
return "";
}
}
};
editText.setFilters(new InputFilter[]{inputFilter});
}
/**
* 设置颜色渐变,从上到下渐变
*/
protected void setTextColorChanged(TextView textView, String startColor, String endColor) {
/*
CLAMP:边缘拉伸。使用边缘颜色对区域外的范围进行填充
REPEAT:重复模式。在水平和垂直两个方向上重复填充
MIRROR:镜像模式。在水平和垂直两个方向上以镜像的方式重复填充,相邻图像间有间隙*/
Shader shader = new LinearGradient(0, 0, 0, textView.getLineHeight(),
Color.parseColor(startColor), Color.parseColor(endColor), Shader.TileMode.CLAMP);
textView.getPaint().setShader(shader);
}
/**
* 设置HTml网页
*
* @param h5 html字符串
* @param textView textview
*/
protected void setHtml(String h5, TextView textView) {
try {
MyImageGetter myImageGetter = new MyImageGetter(context, textView);
CharSequence sequence;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
sequence = Html.fromHtml(h5, Html.FROM_HTML_MODE_LEGACY, myImageGetter, null);
} else {
sequence = Html.fromHtml(h5);
}
textView.setText(sequence);
} catch (Exception e) {
textView.setText("Html错误");
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Glide.with(getApplicationContext()).pauseRequests();
//解注册eventbus
if (isRegisterEventBus()) {
EventBusUtils.unregister(this);
}
OkGo.cancelTag(OkGo.getInstance().getOkHttpClient(), TAG);
ActivityManager_Singe.getInstance().finishActivity(context);
}
//设置字体为默认大小,不随系统字体大小改而改变
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (newConfig.fontScale != 1)//非默认值
getResources();
super.onConfigurationChanged(newConfig);
}
@Override
public Resources getResources() {
Resources res = super.getResources();
if (res.getConfiguration().fontScale != 1) {//非默认值
Configuration newConfig = new Configuration();
newConfig.setToDefaults();//设置默认
res.updateConfiguration(newConfig, res.getDisplayMetrics());
}
return res;
}
}
可以看到还是很多重复代码的,所以说搞一个BaseActivity是多么有必要
继承自BaseActivity的Activity使用如下:
public class MainActivity extends BaseActivity {
private Button btn1;
@Override
public void widgetClick(View v) {
switch (v.getId()){
case R.id.button:
//用简化了的toast和startActivity
showToast("toast");
startActivity(Main2Activity.class);
break;
}
}
@Override
public void initParms(Bundle parms) {
//解析bundle内容或者设置是否旋转,沉浸,全屏
}
@Override
public View bindView() {
return null;
}
@Override
public int bindLayout() {
return R.layout.activity_main;
}
@Override
public void initView(View view) {
btn1=$(R.id.button);
}
@Override
public void setListener() {
btn1.setOnClickListener(this);
}
@Override
public void doBusiness(Context mContext) {
}
}
其实不仅是Activity要搞一个基类,Fragment也要搞一个基类,这样可以大大减少重复代码,而且管理起来还比较容易,保持了样式的一致,如果想个性化也预留了相应的方法。