简单创建Android(安卓)MVVM模式代码
16lz
2021-01-26
import android.Manifest;import android.Manifest.permission;import android.annotation.SuppressLint;import android.content.Intent;import android.os.Build.VERSION;import android.os.Build.VERSION_CODES;import android.os.Bundle;import android.view.MenuItem;import android.view.WindowManager;import com.afollestad.materialdialogs.MaterialDialog;import com.elvishew.xlog.BuildConfig;import com.elvishew.xlog.XLog;import com.hexavii.core.R;import com.hexavii.core.arch.base.livedata.DataState;import com.hexavii.core.arch.base.viewmodel.BasicAndroidViewModel;import com.hexavii.core.arch.base.viewmodel.BasicViewModel;import com.hexavii.core.arch.tools.permission.RxPermissions;import com.hexavii.core.arch.utils.ToastUtil;import androidx.annotation.CallSuper;import androidx.annotation.NonNull;import androidx.annotation.Nullable;import androidx.appcompat.app.ActionBar;import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.NavUtils;import androidx.core.app.TaskStackBuilder;import androidx.lifecycle.ViewModel;import io.reactivex.Observable;public abstract class BaseActivity extends AppCompatActivity implements IBasicUIProcess { protected static final boolean DEBUG = BuildConfig.DEBUG; private VM mViewModel; protected boolean isPad = false; private MaterialDialog mDialog; @CallSuper @Override protected void onCreate(Bundle savedInstanceState) {// requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); requestPermissions(); if (DEBUG) { XLog.d(getLocalClassName() + ":" + savedInstanceState); } isPad = getResources().getBoolean(R.bool.is_pad); //页面接受的参数方法 initParam(savedInstanceState); mViewModel = getViewModel(); initView(mViewModel); //页面数据初始化方法 initData(savedInstanceState, mViewModel); //页面事件监听的方法,一般用于ViewModel层转到View层的事件注册 initViewObservable(mViewModel); } // 请求权限 @SuppressLint("CheckResult") public void requestPermissions() { RxPermissions perm = RxPermissions.with(this); Observable observable; if (VERSION.SDK_INT >= VERSION_CODES.P) { observable = perm.request(permission.FOREGROUND_SERVICE, permission.CAMERA, permission.READ_PHONE_STATE, permission.READ_EXTERNAL_STORAGE, permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.DISABLE_KEYGUARD); } else { observable = perm.request(permission.CAMERA, permission.READ_PHONE_STATE, permission.READ_EXTERNAL_STORAGE, permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.DISABLE_KEYGUARD); } observable.doOnNext(granted -> { if (!granted) { XLog.i("权限未申请"); ToastUtil.showLongToast(BaseActivity.this, "应用必要权限未授予"); } onPermissionsGranted(granted); }).subscribe(); } protected void onPermissionsGranted(boolean granted) {} @Override protected void onNewIntent(final Intent intent) { super.onNewIntent(intent); if (DEBUG) { XLog.d("onNewIntent: " + getLocalClassName()); } } @Override protected void onRestart() { super.onRestart(); if (DEBUG) { XLog.d("onRestart: " + getLocalClassName()); } } @CallSuper @Override protected void onStart() { super.onStart(); if (DEBUG) { XLog.d("onStart: " + getLocalClassName()); } } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); if (DEBUG) { XLog.d("onRestoreInstanceState: " + getLocalClassName()); } } @CallSuper @Override protected void onResume() { super.onResume(); if (DEBUG) { XLog.d("resume: " + getLocalClassName()); } } @CallSuper @Override protected void onPause() { super.onPause(); if (DEBUG) { XLog.d("stop: " + getLocalClassName()); } } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); if (DEBUG) { XLog.d("onSaveInstanceState: " + getLocalClassName()); } } @Override protected void onStop() { super.onStop(); if (DEBUG) { XLog.d("stop: " + getLocalClassName()); } } @CallSuper @Override protected void onDestroy() { super.onDestroy(); if (DEBUG) { XLog.d("onDestroy: " + getLocalClassName()); } // 解除ViewModel生命周期感应 ViewModel vm = getViewModel(); if (null != vm) { if (vm instanceof BasicViewModel) { getLifecycle().removeObserver((BasicViewModel) vm); } else if (vm instanceof BasicAndroidViewModel) { getLifecycle().removeObserver((BasicAndroidViewModel) vm); } } mViewModel = null; if (null != mDialog) { mDialog.dismiss(); mDialog = null; } } @Override public VM createViewModel() { return null; } @Override public void initView(VM vm) { } @Override public void initParam(@Nullable final Bundle savedInstanceState) { } @Override public void initData(Bundle savedInstanceState, VM vm) { } public VM getViewModel() { if (null == mViewModel) { mViewModel = createViewModel(); } return mViewModel; } @Override public void initViewObservable(VM vm) { if (null != vm) { if (vm instanceof BasicViewModel) { registerStateCallBack(((BasicViewModel) vm).getState()); // 让ViewModel拥有View的生命周期感应 getLifecycle().addObserver((BasicViewModel) vm); } else if (vm instanceof BasicAndroidViewModel) { registerStateCallBack(((BasicAndroidViewModel) vm).getState()); // 让ViewModel拥有View的生命周期感应 getLifecycle().addObserver((BasicAndroidViewModel) vm); } } } protected void registerStateCallBack(DataState state) { state.observe(this, this::onStateChanged); } protected void onStateChanged(Integer state) { if (null != mDialog) { mDialog.dismiss(); mDialog = null; } switch (state) { case DataState.DIALOG_LOADING: mDialog = new MaterialDialog.Builder(this) .content(R.string.api_loading) .progress(true, 0).show(); break; case DataState.CONTENT: break; case DataState.EMPTY: break; case DataState.ERROR: break; case DataState.ACTIVITY_FINISHED: finish(); break; } } /** * 跳转页面 * * @param clz * 所跳转的目的Activity类 */ public void startActivity(Class<?> clz) { startActivity(new Intent(this, clz)); } /** * 跳转页面 * * @param clz * 所跳转的目的Activity类 * @param bundle * 跳转所携带的信息 */ public void startActivity(Class<?> clz, Bundle bundle) { Intent intent = new Intent(this, clz); if (bundle != null) { intent.putExtras(bundle); } startActivity(intent); } /** * 跳转容器页面 * * @param canonicalName * 规范名 : Fragment.class.getCanonicalName() */ public void startContainerActivity(String canonicalName) { startContainerActivity(canonicalName, null); } /** * 跳转容器页面 * * @param canonicalName * 规范名 : Fragment.class.getCanonicalName() * @param bundle * 跳转所携带的信息 */ public void startContainerActivity(String canonicalName, Bundle bundle) { Intent intent = new Intent(this, ContainerActivity.class); intent.putExtra(ContainerActivity.FRAGMENT, canonicalName); if (bundle != null) { intent.putExtra(ContainerActivity.BUNDLE, bundle); } startActivity(intent); } protected void setDisplayHomeAsUpEnable(boolean enable) { // Show the Up button in the action bar. ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(enable); } } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == android.R.id.home) { Intent upIntent = NavUtils.getParentActivityIntent(this); if (null == upIntent) { finish(); } else if (NavUtils.shouldUpRecreateTask(this, upIntent)) { // This activity is NOT part of this app's task, so create a new task // when navigating up, with a synthesized back stack. TaskStackBuilder.create(this) // Add all of this activity's parents to the back stack .addNextIntentWithParentStack(upIntent) // Navigate up to the closest parent .startActivities(); } else { // This activity is part of this app's task, so simply // navigate up to the logical parent activity. NavUtils.navigateUpTo(this, upIntent); } return true; } return super.onOptionsItemSelected(item); } @Override public void startActivity(final Intent intent) { super.startActivity(intent); overridePendingTransition(R.anim.fade_out, R.anim.fade_in); }}
BaseActivity创建新的类依赖于它
然后创建BAsicViewModel
import androidx.lifecycle.Lifecycle;import androidx.lifecycle.LifecycleOwner;import androidx.lifecycle.MutableLiveData;import androidx.lifecycle.ViewModel;public class BasicViewModel extends ViewModel implements IBasicViewModel { private DataState mState; private MutableLiveData mTitle; public DataState getState() { if (mState == null) { mState = DataState.getInstance(); } return mState; } public MutableLiveData getNavTitle() { if (mTitle == null) { mTitle = new MutableLiveData<>(); } return mTitle; } @Override public void onAny(LifecycleOwner owner, Lifecycle.Event event) { } @Override public void onCreate() { } @Override public void onDestroy() { } @Override public void onStart() { } @Override public void onStop() { } @Override public void onResume() { } @Override public void onPause() { }}
DataState类
import androidx.lifecycle.MutableLiveData;public class DataState extends MutableLiveData { public static final int ACTIVITY_FINISHED = -2; public static final int DIALOG_LOADING = -1; public static final int LOADING = 0; public static final int CONTENT = 2; public static final int EMPTY = 3; public static final int ERROR = 4; public void setActivityFinished() { setValue(ACTIVITY_FINISHED); } public void postActivityFinished() { postValue(ACTIVITY_FINISHED); } public void setDialogLoading() { setValue(DIALOG_LOADING); } public void postDialogLoading() { postValue(DIALOG_LOADING); } public void setLoading() { setValue(LOADING); } public void postLoading() { postValue(LOADING); } public void setContent() { setValue(CONTENT); } public void postContent() { postValue(CONTENT); } public void setEmpty() { setValue(EMPTY); } public void postEmpty() { postValue(EMPTY); } public void setError() { setValue(ERROR); } public void postError() { postValue(ERROR); } public static DataState getInstance() { return new DataState(); }}
然后在activity_xxxml中设置
这段代码一定要在
主界面Activity可以这么写
package com.hexavii.facepassage.compare.ui;import android.content.Context;import android.content.Intent;import android.os.Bundle;import androidx.databinding.DataBindingUtil;import androidx.lifecycle.ViewModelProvider;import com.hexavii.core.arch.base.BaseActivity;import com.hexavii.core.arch.tools.systemui.SystemUiHelper;import com.hexavii.facepassage.R;import com.hexavii.facepassage.compare.viewmodel.FaceCompareViewModel;import com.hexavii.facepassage.databinding.ActivityFaceCompareBinding;public class FaceCompareActivity extends BaseActivity { public static void start(Context context,int value) { Intent starter = new Intent(context, FaceCompareActivity.class); starter.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TASK); starter.putExtra("type",value); context.startActivity(starter); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onWindowFocusChanged(boolean hasFocus) { if (hasFocus) { SystemUiHelper uiHelper = new SystemUiHelper(this, SystemUiHelper.LEVEL_IMMERSIVE, SystemUiHelper.FLAG_IMMERSIVE_STICKY); uiHelper.hide(); } } @Override public void initView(FaceCompareViewModel faceCompareViewModel) { ActivityFaceCompareBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_face_compare); binding.setViewModel(getViewModel()); binding.setLifecycleOwner(this); } @Override public void initData(Bundle savedInstanceState, FaceCompareViewModel faceCompareViewModel) { super.initData(savedInstanceState, faceCompareViewModel); } @Override public FaceCompareViewModel createViewModel() { return new ViewModelProvider(this).get(FaceCompareViewModel.class); } @Override public void initViewObservable(FaceCompareViewModel vm) { super.initViewObservable(vm); vm.getCheckState().observe(this, state -> { if (null == state ) { return; } }); }}
viewModel这么实现
package com.hexavii.facepassage.compare.viewmodel;import androidx.lifecycle.MutableLiveData;import com.hexavii.core.arch.base.viewmodel.BasicViewModel;public class FaceCompareViewModel extends BasicViewModel { private MutableLiveData mCheckState = new MutableLiveData<>(); public MutableLiveData getCheckState() { return mCheckState; }}
然后就可以设置xml中的实现了
以下为MVVM 模式 Android端实现 是不是很简单~
更多相关文章
- Android--数据库操作辅助类:SQLiteOpenHelper
- 赵雅智:service_bindService生命周期
- Qt for Android程序沉浸式启动页面(去除标题栏、去除黑屏、保留后
- 2020年最新阿里、字节、腾讯、京东等一线大厂高频面试(Android岗)
- Android:Service生命周期方法与Service启动方式bindService与Star
- android studio项目的导出和导入
- Android(安卓):为你的启动页面SplashActivity 添加动画的几种方法
- 如何抽取一个通用的Android(安卓)Loading页面快速实现加载功能
- WEEX-EEUI 页面的高度问题(页面高度设置为多少才对?)