Android App框架设计 基类BaseActivity
2017-05-26 10:19
471 查看
Android App框架设计 基类BaseActivity
这个基类是自己封装的,不是很完善,之前一直打算写博客却一直没动手
效果
这里进行先断网,再测试,可以看到界面切换的三个状态
1.概述
项目中最常见的界面不外乎 标题栏加上具体内容标题栏:返回按钮 + 标题 + 菜单按钮
具体内容:需要考虑考虑加载状态
这就可以考虑进行封装了,还有一个方法,常用成员变量也可以考虑封装到基类中,方便使用
本基类主要封装内容
1.DataBinding避免findViewById
2.toolbar满足基本要求的封装
3.Activity管理类绑定生命周期
4.界面加载状态切换管理类封装
5.一些常用资源声明为成员变量到基类
代码
BaseActivity传入泛型,主要用于DataBinding绑定xml`public abstract class BaseActivity<T extends ViewDataBinding> extends AppCompatActivity implements View.OnClickListener {`
成员变量
`/** * DataBinding 对象 */ protected T mBinding; /** * 界面状态切换 对象 */ protected VaryViewHelper mHelper; /** * 本Actvitiy类名 */ protected static String ACTIVITY_NAME; /** * onCreate方法中保存的数据 */ protected Bundle savedInstanceState; /** * 上下文 */ protected Activity context; /** * 全局上下文 ,这里进行了强转,需要注意自己的Application实际类名 */ protected App application; /** * 屏幕宽,高, 状态栏高 */ protected int screenWidth, screenHeight, statusBarHeightX;`
主要onCreate初始化
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.savedInstanceState = savedInstanceState; LogUtils.i(ACTIVITY_NAME = getClass().getSimpleName()); context = this; application = (App) getApplication(); screenWidth = ScreenUtils.getScreenWidthPixels(getActivity()); screenHeight = ScreenUtils.getScreenHeightPixels(getActivity()); statusBarHeightX = ScreenUtils.getStatusHeight(getActivity()); ActivityCollector.addActivity(this); //添加进activity管理 mBinding= DataBindingUtil.setContentView(this,setLayoutId()); //获取DataBinding对象 initToolBar(); initView(); initListener(); mHelper = new VaryViewHelper.Builder() //初始化界面状态管理器 ,需要自己写几类布局 .setDataView(findViewById(getRootId())) .setLoadingView(LayoutInflater.from(this).inflate(R.layout.layout_loadingview, null))//加载页,无实际逻辑处理 .setEmptyView(LayoutInflater.from(this).inflate(R.layout.layout_emptyview, null))//空页面,无实际逻辑处理 .setErrorView( LayoutInflater.from(this).inflate(R.layout.layout_errorview, null))//错误页面 .setRefreshListener(new View.OnClickListener() { @Override public void onClick(View v) { mHelper.showLoadingView(); getData(); } }) .build(); mHelper.showLoadingView(); getData(); }
主要进行类DataBinding绑定布局,初始化界面管理类,初始化toolbar等
下面是抽象出来的必须实现的方法
/** * 设置布局 layout 的 资源id */ protected abstract int setLayoutId(); /** *设置除了toolbar 以外的 内容布局content的id ,防止toolbar在页面状态切换时被覆盖 */ protected abstract int getRootId(); /** * 初始化ToolBar */ protected abstract void initToolBar(); /** * 初始化一些非加载数据相关的view */ protected abstract void initView(); /** * 初始化监听 */ protected abstract void initListener(); /** * 获取网络数据,获取数据后也在这里更新数据 */ protected abstract void getData(); /** * BaseActivity已经实现了OnClickListener 接口 ,这里进行了空实现,防止部分界面不需要点击事件,也就不需要实现 * 如果需要直接重写该方法 */ @Override public void onClick(View v) { }
其他工具类 及onDestroy方法接触Activity管理类的管理
@Override
public void onBackPressed() {
finish();
}
@Override protected void onDestroy() { ActivityCollector.removeActivity(this); super.onDestroy(); } /** * Toast工具类 */ public Toast toast; public void showToast(String text) { if (toast == null) { toast = Toast.makeText(context, text, Toast.LENGTH_SHORT); } else { toast.setText(text); } toast.show(); } public void showToast(BaseActivity activity, String text) { if (toast == null) { toast = Toast.makeText(activity, text, Toast.LENGTH_SHORT); } else { toast.setText(text); } toast.show(); } public void showToast(int textId) { showToast(getString(textId)); } public BaseActivity getActivity() { return this; } public Intent getIntent(Class clazz) { return new Intent(context, clazz); } public void startIntent(Class clazz) { startActivity(getIntent(clazz)); } public int dp2px(int dp) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()); } protected void hideStatusBar() { int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN;//隐藏状态栏, 定义全屏参数 Window window = getWindow(); //获得当前窗体对象 window.setFlags(flag, flag);//设置当前窗体为全屏显示 } private long lastClickTime; /** * 实现连续点击两次才退出应用程序 */ public void exit() { if ((System.currentTimeMillis() - lastClickTime) > 2000) { showToast("再按一次退出" + context.getResources().getString(R.string.app_name)); lastClickTime = System.currentTimeMillis(); } else { ActivityCollector.removeAll(); System.exit(0); } }
不需要的工具方法可以删除
其他资源及注意点
toolbar
本基类包含初始化Toolbar内容,旨在统一风格使用ToolBar需要给Activity配上style
主要加上这两条属性
<item name="android:windowNoTitle">true</item> <item name="android:windowActionBar">false</item>
布局文件中必须包含Toolbar
然后在initToolBar实现中进行设置ToolBar
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <layout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include android:id="@+id/include_toolbar" layout="@layout/layout_toolbar"/> <LinearLayout android:id="@+id/content_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> </LinearLayout> </LinearLayout> </layout>
layout_toolbar.xml
<?xml version="1.0" encoding="utf-8"?> <layout> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/id_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" app:popupTheme="@style/ToolbarPopupTheme" android:background="@color/colorPrimary" android:minHeight="?attr/actionBarSize"> <TextView android:id="@+id/toolbar_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:singleLine="true" android:textColor="@android:color/white" android:textSize="18sp"/> </android.support.v7.widget.Toolbar> </layout>
对于toolbar中的menu实现类中进行加载
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.menu_item_four, menu); menu .findItem(R.id.item1) .setVisible(true); menu.findItem(R.id.item2) .setVisible(true); menu.findItem(R.id.item3) .setVisible(true); return true; }
res/menu/menu_item_four.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:visible="false" android:id="@+id/item1" android:title="菜单1"/> <item android:visible="false" android:id="@+id/item2" android:title="菜单2"/> <item android:visible="false" android:id="@+id/item3" android:title="菜单3"/> <item android:visible="false" android:id="@+id/item4" android:title="菜单4"/> </menu>
完整实现类
public class MainActivity extends BaseActivity<ActivityMainBinding> { @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.menu_item_four, menu); menu .findItem(R.id.item1) .setVisible(true); menu.findItem(R.id.item2) .setVisible(true); menu.findItem(R.id.item3) .setVisible(true); return true; } @Override protected void initToolBar() { mBinding.includeToolbar.idToolbar.setTitle(""); mBinding.includeToolbar.toolbarTitle.setText("mainactivity"); setSupportActionBar(mBinding.includeToolbar.idToolbar); ActionBar actionBar = getSupportActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); } @Override protected void initView() { } @Override protected void initListener() { mBinding.btn.setOnClickListener(this); } @Override protected int setLayoutId() { //传入layout布局 return R.layout.activity_main; } @Override protected int getRootId() { //传入布局中除去toolbar部分的布局id return R.id.content_main; } @Override protected void getData() { //网络请求 OkHttpUtils .get() .url("http://gank.io/api/data/Android/10/1") .build() .execute(new GankCallback() { @Override public void requestError(Call call, Exception e, int id) { mHelper.showErrorView();//切换加载错误界面 } @Override public void onResponse(String response, int id) { mBinding.tv.setText(response); mHelper.showDataView();//切换正常界面 } }); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn: break; } } }
需要注意的是 基类初始化 只是初试标题栏等不需要网络数据的部分
在onCreate最后调用getData获取网络数据前,已经切换页面为加载状态
需要在getData实现类中切换回来
因为加载状态时 希望标题栏不被加载界面覆盖,这里的getRootId实现类传入主体内容容器id,不包含toolbar
ActivityCollector
activity管理类/** Desc: activity管理类 */ public class ActivityCollector { public static List<Activity> activitys = new ArrayList<>(); public static void addActivity(Activity activity) { activitys.add(activity);//把传入的Activity添加到List中 } public static void removeActivity(Activity activity) { activitys.remove(activity);//根据传入的Activity来删除 } public static void removeAll() { for (Activity activity : activitys) { if (!activity.isFinishing()) { activity.finish(); } } } /** 除了传来的Activity其他的全部删除 可以传多个Activity */ public static void removeAll(Class<?>... clazz) { boolean isExist = false; for (Activity act : activitys) { for (Class c : clazz) { if (act.getClass().isAssignableFrom(c)) { isExist = true; break; } } if (!isExist) { if (!act.isFinishing()) { act.finish(); } } else { isExist = false; } } } /** 从Activity集合查询, 传入的Activity是否存在 如果存在就返回该Activity,不存在就返回null */ public static Activity getActivity(Class<?> activity) { for (int i = 0; i < activitys.size(); i++) { // 判断是否是自身或者子类 if (activitys.get(i).getClass().isAssignableFrom(activity)) { return activitys.get(i); } } return null; } public static Activity getTopActivity() { return activitys.get(activitys.size()-1); }
}
Demo下载地址
http://download.csdn.net/detail/jiushiwo12340/9852351
参考内容
基于 Android在开发中的实用技巧之BaseActivity
基于DataBinding
基于 Activity加载网络数据切换状态工具
相关文章推荐
- Android App框架设计之编写基类BaseActivity
- Android App框架设计之编写基类BaseActivity
- Android BaseActivity App框架设计BaseActivity封装
- Android中基类BaseActivity的设计与实现
- android app 框架之BaseActivity
- Android设计模式之Activity基类封装
- 【慕课实战】Android通用框架设计与完整电商APP开发
- Android通用框架设计与完整电商APP开发一
- android应用框架搭建之BaseActivity
- Android当中的MVP模式(六)View 层 Activity 的基类--- BaseMvpActivity 的封装
- android应用框架设计之Activity管理类:AppManager
- Android模板设计模式之 - 构建整个应用的BaseActivity
- Android 基类BaseActivity的封装
- Android快速开发框架Android_BaseLib,集成了常用工具类,自定义View控件,Base基类封装,常用开源框架
- Android实战:手把手实现“捧腹网”APP(二)-----捧腹APP原型设计、实现框架选取
- android应用框架搭建------BaseActivity
- Android 基类BaseActivity的封装
- app只有一个activity的ui框架设计猜想
- Android软硬整合设计与框架揭秘: HAL&Framework &Native Service &App&Browser架构设计与实战开发
- Android基类Activity的设计