Android BaseActivity的设计(一)

tech2022-10-20  108

Android开发中BaseActivity在程序设计对于项目的架构重要性不言而喻,一个好的BaseActivity设计可以让项目的Activity代码看起来更加简洁且易编写,同时BaseActivity也是MVC,MVP和MVVM架构体现。

BaseActivity使用场景 1 多个子类有公有的方法,并且逻辑基本相同时。 2 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。 3 重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束其行为。 ①MVC的BaseActivity 没有加ButterKnife需要可以加上,EventBus也没加,需要的可以加上

public abstract class BaseActivity extends AppCompatActivity implements View.OnClickListener{ //获取TAG的activity名称 protected final String TAG = this.getClass().getSimpleName(); //设置子activity布局 FrameLayout frameLayout; //title 如果 return null 则隐藏 RelativeLayout rlTitle; //返回按钮 LinearLayout llBack; //title文字 TextView tvTitleBase; //右侧按钮 public Button btnRightBase; LinearLayout llRightBase; //获取上下文 public Context mContext; //progressDialog 可以用自己自定义的Loading private ProgressDialog progressdialog; //是否有返回键 public boolean isHaveBack = true; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = this; //Activity管理 ActivityUtil.getInstance().addActivity(this); //设置布局前处理一些逻辑 init(savedInstanceState); //设置布局 if (setLayoutResourceID() != 0) { setContentView(R.layout.activity_base); //ButterKnife.bind(this); 如果有需要可以在这里设置 initBaseView(); } //初始化控件 设置了ButterKnife 初始化控件就不需要了 initView(); //设置数据 initData(); //设置监听 initListener(); } /** * 设置布局前处理一些逻辑和设置 * * @param savedInstanceState bundle */ protected void init(Bundle savedInstanceState) { } /** * 基础View设置 */ private void initBaseView() { llBack = findViewById(R.id.ll_back_base); tvTitleBase = findViewById(R.id.tv_title_base); frameLayout = findViewById(R.id.fl_base_content); rlTitle = findViewById(R.id.rl_title_base); btnRightBase = findViewById(R.id.btn_right_base); llRightBase = findViewById(R.id.ll_right_base); if (StringUtil.isNotEmpty(initTitle())) { tvTitleBase.setText(initTitle()); } else { rlTitle.setVisibility(View.GONE); } if (isHaveBack) { llBack.setVisibility(View.VISIBLE); llBack.setOnClickListener(view -> finish()); } else { llBack.setVisibility(View.GONE); } btnRightBase.setOnClickListener(view -> rightBtnClickListener()); View baseView = LayoutInflater.from(mContext).inflate(setLayoutResourceID(), frameLayout, false); frameLayout.addView(baseView); } /** * 设置布局 * return 布局 */ @LayoutRes protected abstract int setLayoutResourceID(); /** * 初始化控件 */ protected abstract void initView(); /** * 设置title * * @return title */ protected abstract String initTitle(); /** * 设置数据 */ protected void initData() { } /** * 设置监听 */ protected void initListener() { } @Override public void onClick(View view) { } /** * 设置右边Button样式 * * @param resource */ public void setRightBtnResource(int resource) { if (resource != 0) { llRightBase.setVisibility(View.VISIBLE); btnRightBase.setBackground(ContextCompat.getDrawable(mContext, resource)); } } /** * 右边Button的点击事件 */ protected void rightBtnClickListener() { } /** * show shotToast * * @param msg 提示内容 */ public void showToast(String msg) { if (StringUtil.isEmpty(msg)) { return; } Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show(); } /** * showProgress * * @param msg 提示内容 */ public void showProgress(String msg) { if (progressdialog == null) { progressdialog = new ProgressDialog(mContext); } progressdialog.setTitle("请等待..."); progressdialog.setMessage(msg); progressdialog.show(); } /** * dismissProgress */ protected void dismissProgress() { if (progressdialog != null) { progressdialog.dismiss(); } } /** * 普通跳转 * * @param activity activity */ protected void jumpToActivity(Class<?> activity) { startActivity(new Intent(mContext, activity)); } /** * 保证同一按钮在1秒内只会响应一次点击事件 */ public abstract class OnSingleClickListener implements View.OnClickListener { //两次点击按钮之间的间隔,目前为1000ms private static final int MIN_CLICK_DELAY_TIME = 1000; private long lastClickTime; public abstract void onSingleClick(View view); @Override public void onClick(View view) { long curClickTime = System.currentTimeMillis(); if ((curClickTime - lastClickTime) >= MIN_CLICK_DELAY_TIME) { lastClickTime = curClickTime; onSingleClick(view); } } } @Override protected void onDestroy() { super.onDestroy(); ActivityUtil.getInstance().removeActivity(this); } }

②BaseActivity布局(可以自定义,如果右上角有多个控件也可以自己添加)

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:id="@+id/rl_title_base" style="@style/Panel.Title"> <LinearLayout android:id="@+id/ll_back_base" android:layout_width="48dp" android:layout_height="48dp" android:gravity="center_vertical" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/account_ic_back" android:clickable="false" android:minWidth="0dp" android:minHeight="0dp" /> </LinearLayout> <TextView android:id="@+id/tv_title_base" style="@style/TextView.Title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:singleLine="true" /> <LinearLayout android:id="@+id/ll_right_base" android:layout_width="48dp" android:layout_height="48dp" android:layout_alignParentTop="true" android:layout_alignParentRight="true" android:background="@drawable/selector_topbar_button" android:gravity="center_vertical" android:orientation="vertical" android:visibility="gone"> <Button android:id="@+id/btn_right_base" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/scan_icon" android:clickable="false" android:minWidth="0dp" android:minHeight="0dp" /> </LinearLayout> </RelativeLayout> <FrameLayout android:id="@+id/fl_base_content" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>

③附上ActivityUtil(Activity管理类)

public class ActivityUtil{ private static final String TAG = "ActivityUtil"; /** * 单一实例 */ private static ActivityUtil sActivityUtil; /** * Activity堆栈 Stack:线程安全 */ public Stack<Activity> mActivityStack = new Stack<>(); /** * 私有构造器 无法外部创建 */ private ActivityUtil() { } /** * 获取单一实例 双重锁定 * @return this */ public static ActivityUtil getInstance() { if (sActivityUtil == null) { synchronized (ActivityUtil.class) { if (sActivityUtil == null) { sActivityUtil = new ActivityUtil(); } } } return sActivityUtil; } /** * 添加Activity到堆栈 */ public void addActivity(Activity activity) { mActivityStack.add(activity); } /** * 移除堆栈中的Activity * @param activity Activity */ public void removeActivity(Activity activity) { if (activity != null && mActivityStack.contains(activity)) { mActivityStack.remove(activity); } } /** * 获取当前Activity (堆栈中最后一个添加的) * @return Activity */ public Activity getCurrentActivity() { return mActivityStack.lastElement(); } /** * 获取指定类名的Activity */ public Activity getActivity(Class<?> cls) { if (mActivityStack != null) for (Activity activity : mActivityStack) { if (activity.getClass().equals(cls)) { return activity; } } return null; } /** * 结束当前Activity (堆栈中最后一个添加的) */ public void finishCurrentActivity() { Activity activity = mActivityStack.lastElement(); finishActivity(activity); } /** * 结束指定的Activity * @param activity Activity */ public void finishActivity(Activity activity) { if (activity != null && mActivityStack.contains(activity)) { mActivityStack.remove(activity); activity.finish(); } } /** * 结束指定类名的Activity * @param clazz Activity.class */ public void finishActivity(Class<?> clazz) { for (Activity activity : mActivityStack) { if (activity.getClass().equals(clazz)) { finishActivity(activity); break; } } } /** * 结束所有Activity */ public void finishAllActivity() { for (int i = mActivityStack.size() - 1; i >= 0; i--) { if (mActivityStack.get(i) != null) { finishActivity(mActivityStack.get(i)); } } mActivityStack.clear(); } /** * 结束某个Activity之外的所有Activity */ public void finishAllActivityExcept(Class<?> clazz) { for (int i = mActivityStack.size() - 1; i >= 0; i--) { if (mActivityStack.get(i) != null && !mActivityStack.get(i).getClass().equals(clazz)) { finishActivity(mActivityStack.get(i)); } } } /** * 退出应用程序 */ public void exitApp() { try { finishAllActivity(); } catch (Exception e) { e.printStackTrace(); } finally { System.exit(0); } } /** * 判断某个Activity 界面是否在前台 * @param context * @param className 某个界面名称 * @return */ public static boolean isForeground(Context context, String className) { if (context == null || TextUtils.isEmpty(className)) { return false; } ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(1); if (list != null && list.size() > 0) { ComponentName cpn = list.get(0).topActivity; if (className.equals(cpn.getClassName())) { return true; } } return false; } }

④基础用法 可以自己扩展方法

public class TestActivity extends BaseActivity { Button button; Button button2; //设置布局 @Override protected int setLayoutResourceID() { return R.layout.activity_test; } //在设置布局之前做一些操作设置或者接收数据 @Override protected void init(Bundle savedInstanceState) { super.init(savedInstanceState); //是否有返回按钮 默认有 //isHaveBack=false; } //初始化控件 如果用了ButterKnife 初始化控件就不需要了 @Override protected void initView() { button = findViewById(R.id.button_test); button2 = findViewById(R.id.button_test2); } //给控件设置数据 @Override protected void initData() { super.initData(); //做网络请求前 showProgress("xxxx"); //网络请求结束 dismissProgress(); //toast short showToast("xxx"); //普通跳转 //jumpToActivity(xxx.activity); } @Override protected void initListener() { super.initListener(); //设置1s内单次点击事件 button.setOnClickListener(new OnSingleClickListener() { @Override public void onSingleClick(View view) { } }); //普通点击事件 button2.setOnClickListener(this); } @Override public void onClick(View view) { super.onClick(view); switch (view.getId()) { case R.id.button_test2: break; default: break; } } //设置 title 如果没有title 可以 return null 就没有title了 @Override protected String initTitle() { return "测试title"; } }

后续会推出基于MVP的BaseMVPActivity的封装,如果有自己需要的方法也可以自己抽出来放在BaseActivity中,本文主要是提供一个思路,具体实现根据个人需要。

最新回复(0)