(一) 抽取Activity基类--BaseActivity
2016-05-05 23:24
337 查看
为什么要抽取Activity基类?
主要原因有两个:第一个原因是方便代码编写,减少重复代码,快速开发。
第二个原因是优化代码结构,降低耦合度,方便修改。
还有一些其他原因:提高代码可读性,代码显得井井有条,看起来很优美。
举例
比如我们可以抽取一个最简单的BaseActivity。
public abstract class MyBaseActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 初始化ui initView(); // 初始化数据 initData(); // 添加监听器 initListener(); } // 初始化ui protected abstract void initView(); // 初始化数据 protected abstract void initData(); // 添加监听器 4000 protected abstract void initListener(); }
其中initView()用来初始化ui,initData()用来处理数据,initListener()用来给控件添加监听器。注意BaseActivity类为抽象类,initView()、initData()和initListener()这三个方法为抽象方法,子类必须实现。
那么我们怎么使用BaseActivity呢?
我们只需要将我们需要写的Activity继承BaseActivity即可,如:public class MyActivity extends MyBaseActivity { @Override protected void initView() { // 用来出来初始化视图 // 别忘了setContentView(R.layout.XXX);加载布局文件 // findViewByid } @Override protected void initData() { // 用来初始化数据以及处理数据 } @Override protected void initListener() { // 用来给控件添加监听器,可以在里面写如btn.setonClickListener(){}; .....等监听器。 } }
注意在initView()中别忘了使用setContentView(R.layout.xxx)方法加载布局文件。
这样看起来是不是很有层次?是不是可读性更高?和所有代码全写在oncreate()方法中相比是不是代码优美许多?
你可能会问,这代码量和不用基类差不多吗?它的好处当然不止如此,上面的写法只是最简单的写法,让你体会一下这种写法而已。我们可以BaseActivity添加一些公共的代码。如:
我们可以在BaseActivity中添加这样一个方法
public void openActivity(Class<?> targetActivityClass, Bundle bundle) { Intent intent = new Intent(this, targetActivityClass); if (bundle != null) { intent.putExtras(bundle); } startActivity(intent); }
这样我们就不用每次跳转Activity的时候都去new一个Intent,然后startActivity(intent);有了它我们只需一行代码就搞定:
openActivity(xxxActivity,bundler)
但是你会问,我们大部分时候是不用携带参数bundle的,那怎么办?
那么我们可以在此基础上再添加几个方法:
这是不携带bundle参数的
public void openActivity(Class<?> targetActivityClass) { openActivity(targetActivityClass, null); }
这是打开新的Activity并关闭当前Activity的方法:
public void openActivityAndCloseThis(Class<?> targetActivityClass) { openActivity(targetActivityClass); this.finish(); }
我们还可以添加这样的方法:
// short吐司 public void showShort(String text) { Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); } // long吐司 public void showLong(String text) { Toast.makeText(this, text, Toast.LENGTH_LONG).show(); }
那么我们写吐司的时候就不用写那么长一段代码了,只需showShort(text),showLong(text)就可以实现了。
还有的时候我们需要添加许多监听器的时候,我们可以给BaseActivity实现onClickListener()接口:
public abstract class MyBaseActivity extends Activity implements OnClickListener {......}
然后再我们自己的Acitvity中重写onClick()方法即可:
public class MyActivity extends MyBaseActivity { @Override protected void initView() { // 用来出来初始化视图 // 别忘了setContentView(R.layout.XXX);加载布局文件 // findViewByid } @Override protected void initData() { // 用来初始化数据以及处理数据 } @Override protected void initListener() { // 用来给控件添加监听器,可以在里面写如btn.setonClickListener(){}; .....等监听器。 } @Override public void onClick(View arg0) { switch (arg0.getId()) { //控件id case R.id.xxx: break; default: break; } } }
还有一些时候我们的Activity需要用到Fragment的时候,我们的基类BaseActivity可以通过继承FragmentActivity实现:
public abstract class MyBaseActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 初始化ui
initView();
// 初始化数据
initData();
// 添加监听器
initListener();
}
// 初始化ui protected abstract void initView(); // 初始化数据 protected abstract void initData(); // 添加监听器 protected abstract void initListener(); /* * ************Fragement相关方法************************************************ * */ private Fragment currentFragment; /** Fragment替换(当前destrory,新的create) */ public void fragmentReplace(int target, Fragment toFragment, boolean backStack) { FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); String toClassName = toFragment.getClass().getSimpleName(); if (manager.findFragmentByTag(toClassName) == null) { transaction.replace(target, toFragment, toClassName); if (backStack) { transaction.addToBackStack(toClassName); } transaction.commit(); } } /** Fragment替换(核心为隐藏当前的,显示现在的,用过的将不会destrory与create) */ public void smartFragmentReplace(int target, Fragment toFragment) { FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); // 如有当前在使用的->隐藏当前的 if (currentFragment != null) { transaction.hide(currentFragment); } String toClassName = toFragment.getClass().getSimpleName(); // toFragment之前添加使用过->显示出来 if (manager.findFragmentByTag(toClassName) != null) { transaction.show(toFragment); } else {// toFragment还没添加使用过->添加上去 transaction.add(target, toFragment, toClassName); } transaction.commit(); // toFragment更新为当前的 currentFragment = toFragment; } /***********************************************************************/
}
注意FragmentActivity和Fragment使用supportV4包里的
其中的fragmentReplace(int target, Fragment toFragment, boolean backStack)方法和
smartFragmentReplace(int target, Fragment toFragment)方法是用来处理Fragment切换的,我们切换fragment的时候只需调用这两个方法即可,不用每次敲一大段冗余的代码。
诸如此类,只要我们多个Activity可能要用的方法都可以写到BaseActivity中,这样就可以减少一些重复的代码了。读者可自行添加自己需要的一些公共方法到BaseActivity中。
下面是笔者使用的比较多的一个BaseActivity
/**
* BaseActivity
*
* @author RaphetS
*
*/
public abstract class BaseActivity extends FragmentActivity {
/** 用来保存所有已打开的Activity */
private static Stack<Activity> listActivity = new Stack<Activity>();
/** 提示信息 **/
private Toast mToast;
/** 记录上次点击按钮的时间 **/
private long lastClickTime;
/** 按钮连续点击最低间隔时间 单位:毫秒 **/
public final static int CLICK_TIME = 500;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置activity为无标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 将activity推入栈中
listActivity.push(this);
// 初始化ui
initUI();
// 初始化数据
initData();
// 事件监听
initListener();
}
/** 初始化ui **/
protected abstract void initUI();
/** 初始化数据 **/
protected abstract void initData();
/** 初始化监听 **/
protected abstract void initListener();
@Override
protected void onSaveInstanceState(Bundle outState) {
saveInstanceState(outState);
super.onSaveInstanceState(outState);
}
/** 保存activity状态 **/
protected void saveInstanceState(Bundle outState) {
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
public void onBack(View v) {
finish();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
// 从栈中移除当前activity
if (listActivity.contains(this)) {
listActivity.remove(this);
}
}
/********************** activity跳转 **********************************/
public void openActivity(Class<?> targetActivityClass) { openActivity(targetActivityClass, null); }
public void openActivity(Class<?> targetActivityClass, Bundle bundle) { Intent intent = new Intent(this, targetActivityClass); if (bundle != null) { intent.putExtras(bundle); } startActivity(intent); }
public void openActivityAndCloseThis(Class<?> targetActivityClass) { openActivity(targetActivityClass); this.finish(); }
public void openActivityAndCloseThis(Class<?> targetActivityClass, Bundle bundle) {
openActivity(targetActivityClass, bundle);
this.finish();
}
/***************************************************************/
/** 验证上次点击按钮时间间隔,防止重复点击 */
public boolean verifyClickTime() {
if (System.currentTimeMillis() - lastClickTime <= CLICK_TIME) {
return false;
}
lastClickTime = System.currentTimeMillis();
return true;
}
/** 收起键盘 */
public void closeInputMethod() {
// 收起键盘
View view = getWindow().peekDecorView();// 用于判断虚拟软键盘是否是显示的
if (view != null) {
InputMethodManager inputmanger = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
inputmanger.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
/**
* 获取string
*
* @param mRid
* @return
*/
public String getStringMethod(int mRid) {
return this.getResources().getString(mRid);
}
/**
* 获取demin
*
* @param mRid
* @return
*/
protected int getDemonIntegerMethod(int mRid) {
return (int) this.getResources().getDimension(mRid);
}
/**
* 关闭所有(前台、后台)Activity,注意:请已BaseActivity为父类
*/
protected static void finishAll() {
int len = listActivity.size();
for (int i = 0; i < len; i++) {
Activity activity = listActivity.pop();
activity.finish();
}
}
/***************** 双击退出程序 ************************************************/
private long exitTime = 0;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (KeyEvent.KEYCODE_BACK == keyCode) {
// 判断是否在两秒之内连续点击返回键,是则退出,否则不退出
if (System.currentTimeMillis() - exitTime > 2000) {
Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
// 将系统当前的时间赋值给exitTime
exitTime = System.currentTimeMillis();
} else {
finishAll();
}
return true;
}
return super.onKeyDown(keyCode, event);
}
/*
* ************Fragement相关方法************************************************
*
*/
private Fragment currentFragment;
/** Fragment替换(当前destrory,新的create) */
public void fragmentReplace(int target, Fragment toFragment, boolean backStack) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
String toClassName = toFragment.getClass().getSimpleName();
if (manager.findFragmentByTag(toClassName) == null) {
transaction.replace(target, toFragment, toClassName);
if (backStack) {
transaction.addToBackStack(toClassName);
}
transaction.commit();
}
}
/** Fragment替换(核心为隐藏当前的,显示现在的,用过的将不会destrory与create) */
public void smartFragmentReplace(int target, Fragment toFragment) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
// 如有当前在使用的->隐藏当前的
if (currentFragment != null) {
transaction.hide(currentFragment);
}
String toClassName = toFragment.getClass().getSimpleName();
// toFragment之前添加使用过->显示出来
if (manager.findFragmentByTag(toClassName) != null) {
transaction.show(toFragment);
} else {// toFragment还没添加使用过->添加上去
transaction.add(target, toFragment, toClassName);
}
transaction.commit();
// toFragment更新为当前的
currentFragment = toFragment;
}
/***********************************************************************/
}
相关文章推荐
- MySQL 优化
- 注册表的组织结构
- Google排名优化的几个影响因素
- DB2优化(简易版)
- Mysql limit 优化,百万至千万级快速分页 复合索引的引用并应用于轻量级框架
- C#中尾递归的使用、优化及编译器优化
- 对优化Ruby on Rails性能的一些办法的探究
- 优化Ruby脚本效率实例分享
- Asp编码优化技巧
- SQLSERVER的非聚集索引结构深度理解
- 如何监测和优化OLAP数据库
- 调整SQLServer2000运行中数据库结构
- mysql -参数thread_cache_size优化方法 小结
- 深入学习SQL Server聚合函数算法优化技巧
- C#基础语法:结构和类区别详解
- 深入c# 类和结构的区别总结详解
- c#结构和类的相关介绍
- C#中结构(struct)的部分初始化和完全初始化实例分析
- C#中类与结构的区别实例分析
- C#枚举类型与结构类型实例解析