Android 基类BaseActivity的封装
2018-02-18 23:38
387 查看
Android 基类BaseActivity的封装
原创 2017年04月08日 14:01:20标签:android /
activity封装
4717
摘要
本篇总结了前人写的BaseActivity,自己在开发过程中也添添补补,删删改改,现在总结下。本篇很多知识借鉴和学习了知乎上iYng大大的回答,先感谢一波。顺便上原文链接:
https://www.zhihu.com/question/47045239/answer/105086885
正文
一般来说,不同的项目的BaseActivity不尽相同,根据不同的业务逻辑和功能需求,会有很多区别。这里总结了一些,如下:视图相关
一般的Activity里都会用到很多的findViewById这个方法,而且每次都要强制类型转换,这样会显得很繁琐,如果在BaseActivity里封装好,就能省事:protected <T extends View> T findView(int id) { return (T) findViewById(id); }1
2
3
4
这样只要是继承了BaseActivity就能轻松使用
LinearLayout llContent = findView(R.id.ll_content);,免去了诸多类型转换的麻烦。
然后说起视图,一般的Activity里都会需要初始化视图和数据,所以可以暴露两个方法initView()和initData():
public abstract void initData(); public abstract void initView();1
2
3
4
然后在setContentView里去调用,一般都是先initView,然后再initData:
@Override public void setContentView(@LayoutRes int layoutResID) { super.setContentView(layoutResID); initView(); initData(); } @Override public void setContentView(View view) { super.setContentView(view); initView(); initData(); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
这样子类里都必须重写initView()和initData()了,逻辑也能清晰点,不然什么东西都放在onCreate里,就很乱了;
用户模块(业务相关【可选】)
不过一般的app,只要是有登录的,就会有用户模块,也会根据用户标识id去进行一些网络操作,所以用户模块可以在BaseActivity中暴露一些方法,比如用户id的获取:public int getUid() { if (UserManager().getUid() != null) { if (UserManager().getUid().equals("")) { return 0 ; } } return Integer.parseInt(UserManager().getUid()) ; }1
2
3
4
5
6
7
8
9
这里就是返回了SharedPreference里存储的用户id,在用户id大量被使用的场景下,这样的封装还是很有必要的,使用起来也更便捷。当然如果只是纯展示的app就不一定需要了,或许显得多余。
界面间跳转传参
很多时候,Activity之间都会传参,所以可以封装一个参数处理的函数initParam(),在BaseActivity的onCreate里去判断是否有参数传过来;@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ...... if (savedInstanceState != null) { initParam(savedInstanceState); } else if (getIntent() != null && getIntent().getExtras() != null) { initParam(getIntent().getExtras()); } }1
2
3
4
5
6
7
8
9
10
11
12
13
然后把initParam()方法暴露给子类:
protected void initParam(Bundle bundle) { }1
2
3
4
这个方法并不是必须重写的,因为传参也没有想象中那么多,并不需要强制重写这个方法。
调试和吐司
一般会在Application类里去定义一个isDebug来判断是否开启调试(开发者模式):public class TApplication extends Application { public static boolean isDebug = true ; public static String APP_NAME ; }1
2
3
4
5
6
在BaseActivity里,我们可以把isDebug作为总开关,然后控制是否显示调试信息:
public void TLog(String msg) { if (isDebug) { Log.d(APP_NAME, msg); } }1
2
3
4
5
6
这样一键关闭调试,不用去一个个删项目里的Log信息,是不是很赞?
每次Toast,都用
Toast.makeText(...).show();是不是很烦?那么可以在BaseActivity里封装下,比如:
public void toast(String text) { ToastUtils.show(text); } public void toast(int resId) { ToastUtils.show(String.valueOf(resId)); }1
2
3
4
5
6
7
8
这里ToastUtils就是一个Toast封装类,里面的内容估计大家都懂。然后这样一来,所有子类在使用时,只需要潇洒写一句
toast("xxxx")就行了,当然也可以一并封装
Toast.LENGTH_LONG和
Toast.LENGTH_SHORT,按需封装吧。
其他
软键盘
有的app里,用户输入的情景会比较多,这个时候,软键盘的隐藏就用的多了,用户输入完之后,或者用户点击屏幕空白处,都应该去隐藏软键盘,这样的话,可以考虑在BaseActivity里写隐藏的方法:/** * 隐藏软件盘 */ public void hideSoftInput() { InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); if (getCurrentFocus() != null) { imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); } } /** * 点击软键盘之外的空白处,隐藏软件盘 * @param ev * @return */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { View v = getCurrentFocus(); if (ToolUtil.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 void showInputMethod(){ if (getCurrentFocus() != null){ InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); imm.showSoftInputFromInputMethod(getCurrentFocus().getWindowToken(),0); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
上面3个方法也是很实用的。dispatchTouchEvent方法不需要手动调用,只要是有点击事件,并且点击在软键盘和EditText区域外,就会隐藏软键盘。
防止快速点击
有时候,用户(特别是测试猿)会疯狂的点击app,这一举动的原因和意义不明,但是我们可以设置防止快速点击给app造成的伤害和负担:private boolean fastClick() { long lastClick = 0; if (System.currentTimeMillis() - lastClick <= 1000) { return false; } lastClick = System.currentTimeMillis(); return true; }1
2
3
4
5
6
7
8
9
这样在1秒之内只会响应一次,麻麻再也不用担心我手抽筋乱点了。
那么怎么用呢?举个栗子,可以在onClick接口里去判断下嘛:
/** View点击 **/ public abstract void widgetClick(View v); @Override public void onClick(View v) { if (fastClick()) widgetClick(v); }1
2
3
4
5
6
7
8
9
这个写法的话,就是子类必须重写widgetClick(View v)这个方法,其实就是onClick外面又封装了一层。使用的时候,把widgetClick当做onClick就行。个人不喜欢BaseActivity里写一堆abstract方法,所以这个widgetClick可以酌情参考。
页面跳转:startActivity、startActivityForResult
这个也是可选的,可以封装下,达到每次跳转不需要传this或者XXXXX.this这种参数:public void startActivity(Class<?> clz) { startActivity(clz, null); } /** *携带数据的页面跳转 * @param clz * @param bundle */ 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打开编辑界面 * * @param cls * @param bundle * @param requestCode */ 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); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
这些方法还是很便捷的,使用时可以简单的使用
startActivity(MainActivity.class);,也可以传Bundle参数。
是否允许全屏
设置一个成员变量mAllowFullScreen:/** 是否允许全屏 **/ private boolean mAllowFullScreen = true;1
2
3
通过在BaseActivity的onCreate方法里判断mAllowFullScreen来设置是否允许全屏:
if (mAllowFullScreen) { this.getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); requestWindowFeature(Window.FEATURE_NO_TITLE); }1
2
3
4
5
6
7
然后给子类暴露一个方法来设置mAllowFullScreen:
public void setAllowFullScreen(boolean allowFullScreen) { this.mAllowFullScreen = allowFullScreen; }1
2
3
4
设置沉浸式状态栏
跟设置全屏一样一样的:/** 是否沉浸状态栏 **/ private boolean isSetStatusBar = true;1
2
3
然后BaseActivity的onCreate里:
if (isSetStatusBar) { steepStatusBar(); }1
2
3
4
然后定义steepStatusBar()方法,用来设置沉浸式状态栏:
private void steepStatusBar() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // 透明状态栏 getWindow().addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); // 透明导航栏 getWindow().addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); } }1
2
3
4
5
6
7
8
9
10
11
这里就要判断系统版本了。只有在KITKAT以上才有作用。
最后给子类暴露方法,设置 isSetStatusBar的值:
/** * 是否设置沉浸状态栏 * @param isSetStatusBar */ public void setSteepStatusBar(boolean isSetStatusBar) { this.isSetStatusBar = isSetStatusBar; }1
2
3
4
5
6
7
8
设置是否允许屏幕旋转
跟前面两种思路一样,通过判断变量,在onCreate里设置咯:/** 是否禁止旋转屏幕 **/ private boolean isAllowScreenRoate = false;1
2
3
BaseActivity里的onCreate方法:
if (!isAllowScreenRoate) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); }1
2
3
4
5
6
最后暴露方法设置isAllowScreenRoate的值:
public void setScreenRoate(boolean isAllowScreenRoate) { this.isAllowScreenRoate = isAllowScreenRoate; }1
2
3
4
总结
上面的这些方法大都是比较常用的,有些虽然不是很常用,但是写了也会方便一点,把这篇文章当做一个汇总,然后按需使用呗。版权声明:本文为博主原创文章,未经博主允许不得转载。
相关文章推荐
- Android 基类BaseActivity的封装
- Android 基类BaseActivity的封装
- Android当中的MVP模式(六)View 层 Activity 的基类--- BaseMvpActivity 的封装
- 封装BaseActivity基类加沉浸式标题栏 隐藏状态栏 加Di 4000 alogUtils进度条工具类
- Android App框架设计之编写基类BaseActivity
- Android中基类BaseActivity的设计与实现
- Android 运行时权限处理封装在 BaseActivity 中,方便业务申请时只需要简单的 1,2 行代码即可成功处理权限申请
- Android App框架设计 基类BaseActivity
- Android设计模式之Activity基类封装
- Android 6.0权限判断封装的基类 实用在activity和fragment中
- Android 谈谈封装那些事 --BaseActivity 和 BaseFragment(二)
- Android 基类Base的封装
- Android -- 带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(三)
- Android快速开发框架Android_BaseLib,集成了常用工具类,自定义View控件,Base基类封装,常用开源框架
- Android -- 带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(三)
- android常用封装 --- BaseActivity
- Android BaseActivity App框架设计BaseActivity封装
- 《一个Android工程的从零开始》-5、base(四) BaseActivity——方法封装
- Android Activity基类封装
- Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(一)