package com.doumee.lib_coremodel.base; import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.os.Message; import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.PopupWindow; import androidx.annotation.IdRes; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.app.ActivityOptionsCompat; import androidx.databinding.DataBindingUtil; import androidx.databinding.ViewDataBinding; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelStoreOwner; import com.doumee.lib_coremodel.R; import com.doumee.lib_coremodel.base.livedata.MessageEvent; import com.doumee.lib_coremodel.base.livedata.StatusEvent; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; /** * MVVMFrame 框架基于Google官方的 JetPack 构建,在使用MVVMFrame时,需遵循一些规范: * * 如果您继承使用了BaseDialogFragment或其子类,你需要参照如下方式添加@AndroidEntryPoint注解 * * @example Fragment * //------------------------- * @AndroidEntryPoint * public class YourFragment extends BaseDialogFragment { * * } * //------------------------- * * @author Jenly */ public abstract class BaseDialogFragment extends DialogFragment implements IView, BaseNavigator { /** * 请通过 {@link #getVM()}获取,后续版本 {@link #mViewModel}可能会私有化 */ private VM mViewModel; /** * 请通过 {@link #getDB()}获取,后续版本 {@link #mBinding}可能会私有化 */ private VDB mBinding; /** * 请通过 {@link #getRootView()} ()}获取,后续版本 {@link #mRootView}可能会私有化 */ private View mRootView; protected static final float DEFAULT_WIDTH_RATIO = 0.85f; private Dialog mProgressDialog; @Override public void onAttach(Context context) { super.onAttach(context); } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { initDialog(getDialog()); mRootView = createRootView(inflater,container,savedInstanceState); if(isBinding()){ mBinding = DataBindingUtil.bind(mRootView); } initViewModel(); return mRootView; } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); initView(savedInstanceState); initData(savedInstanceState); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); initWindow(getDialog().getWindow()); } protected void initDialog(Dialog dialog){ dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setCanceledOnTouchOutside(false); } protected void initWindow(Window window){ window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); window.getAttributes().windowAnimations = R.style.mvvmframe_dialog_animation; setWindow(window, DEFAULT_WIDTH_RATIO); } /** * 创建 {@link #mRootView} * @param inflater * @param container * @param savedInstanceState * @return */ protected View createRootView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){ return inflater.inflate(getLayoutId(),container,false); } /** * 获取rootView * @return {@link #mRootView} */ protected View getRootView(){ return mRootView; } public T findViewById(@IdRes int id) { return getRootView().findViewById(id); } /** * 初始化 {@link #mViewModel} */ private void initViewModel(){ mViewModel = createViewModel(); if(mViewModel != null){ getLifecycle().addObserver(mViewModel); registerLoadingEvent(); } } private Class getVMClass(){ Class cls = getClass(); Class vmClass = null; while (vmClass == null && cls!= null){ vmClass = getVMClass(cls); cls = cls.getSuperclass(); } if(vmClass == null){ vmClass = (Class) BaseViewModel.class; } return vmClass; } private Class getVMClass(Class cls){ Type type = cls.getGenericSuperclass(); if(type instanceof ParameterizedType){ Type[] types = ((ParameterizedType)type).getActualTypeArguments(); for(Type t : types){ if(t instanceof Class){ Class vmClass = (Class)t; if(BaseViewModel.class.isAssignableFrom(vmClass)){ return vmClass; } }else if(t instanceof ParameterizedType){ Type rawType = ((ParameterizedType)t).getRawType(); if(rawType instanceof Class){ Class vmClass = (Class)rawType; if(BaseViewModel.class.isAssignableFrom(vmClass)){ return vmClass; } } } } } return null; } @Override public void onDestroy() { super.onDestroy(); if(mViewModel!=null){ getLifecycle().removeObserver(mViewModel); } mViewModel = null; if(mBinding!=null){ mBinding.unbind(); } } /** * 注册状态监听 */ protected void registerLoadingEvent(){ mViewModel.getLoadingEvent().observe(getViewLifecycleOwner(), new Observer() { @Override public void onChanged(@Nullable Boolean isLoading) { if(isLoading){ showLoading(); }else{ hideLoading(); } } }); } @Override public void showLoading() { showProgressDialog(); } @Override public void hideLoading() { dismissProgressDialog(); } /** * 注册消息事件 */ protected void registerMessageEvent(@NonNull MessageEvent.MessageObserver observer){ mViewModel.getMessageEvent().observe(getViewLifecycleOwner(),observer); } /** * 注册单个消息事件,消息对象:{@link Message} * @param observer */ protected void registerSingleLiveEvent(@NonNull Observer observer){ mViewModel.getSingleLiveEvent().observe(getViewLifecycleOwner(),observer); } /** * 注册状态事件 * @param observer */ protected void registerStatusEvent(@NonNull StatusEvent.StatusObserver observer){ mViewModel.getStatusEvent().observe(getViewLifecycleOwner(),observer); } /** * 是否使用DataBinding * @return 默认为true 表示使用。如果为false,则不会初始化 {@link #mBinding}。 */ @Override public boolean isBinding(){ return true; } /** * 创建ViewModel * @return 默认为null,为null时,{@link #mViewModel}会默认根据当前Activity泛型 {@link VM}获得ViewModel */ @Override public VM createViewModel(){ return obtainViewModel(getVMClass()); } /** * 获取 ViewModel * @return {@link #mViewModel} */ public VM getVM(){ return mViewModel; } /** * 获取 ViewDataBinding * @return {@link #mBinding} */ public VDB getDB(){ return mBinding; } /** * 通过 {@link #createViewModelProvider(ViewModelStoreOwner)}获得 ViewModel * @param modelClass * @param * @return */ public T obtainViewModel(@NonNull Class modelClass){ return createViewModelProvider(this).get(modelClass); } /** * @deprecated 请使用 {@link #obtainViewModel(Class)} * @param modelClass * @param * @return */ @Deprecated public T getVM(@NonNull Class modelClass){ return obtainViewModel(modelClass); } /** * 创建 {@link ViewModelProvider} * @param owner * @return */ private ViewModelProvider createViewModelProvider(@NonNull ViewModelStoreOwner owner){ return new ViewModelProvider(owner); } //--------------------------------------- protected void finish(){ getActivity().finish(); } protected Intent newIntent(Class cls){ return new Intent(getContext(),cls); } protected Intent newIntent(Class cls, int flags){ Intent intent = newIntent(cls); intent.addFlags(flags); return intent; } protected void startActivity(Class cls){ startActivity(newIntent(cls)); } protected void startActivity(Class cls, int flags){ startActivity(newIntent(cls,flags)); } protected void startActivity(Class cls, @Nullable ActivityOptionsCompat optionsCompat){ startActivity(newIntent(cls),optionsCompat); } protected void startActivity(Class cls, int flags, @Nullable ActivityOptionsCompat optionsCompat){ startActivity(newIntent(cls,flags),optionsCompat); } protected void startActivity(Intent intent, @Nullable ActivityOptionsCompat optionsCompat){ if(optionsCompat != null){ startActivity(intent,optionsCompat.toBundle()); }else{ startActivity(intent); } } protected void startActivityFinish(Class cls){ startActivity(cls); finish(); } protected void startActivityFinish(Class cls, int flags){ startActivity(cls,flags); finish(); } protected void startActivityFinish(Class cls, @Nullable ActivityOptionsCompat optionsCompat){ startActivity(cls,optionsCompat); finish(); } protected void startActivityFinish(Class cls, int flags, @Nullable ActivityOptionsCompat optionsCompat){ startActivity(newIntent(cls,flags),optionsCompat); } protected void startActivityFinish(Intent intent, @Nullable ActivityOptionsCompat optionsCompat){ startActivity(intent,optionsCompat); } protected void startActivityForResult(Class cls, int requestCode){ startActivityForResult(newIntent(cls),requestCode); } protected void startActivityForResult(Class cls, int requestCode, @Nullable ActivityOptionsCompat optionsCompat){ Intent intent = newIntent(cls); if(optionsCompat != null){ startActivityForResult(intent,requestCode,optionsCompat.toBundle()); }else{ startActivityForResult(intent,requestCode); } } //--------------------------------------- protected View inflate(@LayoutRes int id){ return inflate(id,null); } protected View inflate(@LayoutRes int id, @Nullable ViewGroup root){ return LayoutInflater.from(getContext()).inflate(id,root); } protected View inflate(@LayoutRes int id, @Nullable ViewGroup root, boolean attachToRoot){ return LayoutInflater.from(getContext()).inflate(id,root,attachToRoot); } //--------------------------------------- protected void showDialogFragment(DialogFragment dialogFragment){ String tag = dialogFragment.getTag() !=null ? dialogFragment.getTag() : dialogFragment.getClass().getSimpleName(); showDialogFragment(dialogFragment,tag); } protected void showDialogFragment(DialogFragment dialogFragment, String tag) { dialogFragment.show(getFragmentManager(),tag); } protected void showDialogFragment(DialogFragment dialogFragment, FragmentManager fragmentManager, String tag) { dialogFragment.show(fragmentManager,tag); } protected Dialog getProgressDialog(){ return this.mProgressDialog; } protected void dismissDialog(Dialog dialog){ if(dialog != null && dialog.isShowing()){ dialog.dismiss(); } } protected void dismissPopupWindow(PopupWindow popupWindow){ if(popupWindow!=null && popupWindow.isShowing()){ popupWindow.dismiss(); } } protected void dismissProgressDialog(){ dismissDialog(mProgressDialog); } protected void showProgressDialog(){ showProgressDialog(false); } protected void showProgressDialog(boolean isCancel){ showProgressDialog(R.layout.mvvmframe_progress_dialog,isCancel); } protected void showProgressDialog(@LayoutRes int resId){ showProgressDialog(resId,false); } protected void showProgressDialog(@LayoutRes int resId,boolean isCancel){ showProgressDialog(inflate(resId),isCancel); } protected void showProgressDialog(View v){ showProgressDialog(v,false); } protected void showProgressDialog(View v, boolean isCancel){ dismissProgressDialog(); mProgressDialog = BaseProgressDialog.newInstance(getContext()); mProgressDialog.setContentView(v); mProgressDialog.setCanceledOnTouchOutside(isCancel); mProgressDialog.show(); } protected void setDialogWindow(Dialog dialog, float widthRatio){ setWindow(dialog.getWindow(),widthRatio); } protected void setWindow(Window window, float widthRatio){ WindowManager.LayoutParams lp = window.getAttributes(); lp.width = (int)(getWidthPixels() * widthRatio); window.setAttributes(lp); } //--------------------------------------- protected DisplayMetrics getDisplayMetrics(){ return getResources().getDisplayMetrics(); } protected int getWidthPixels(){ return getDisplayMetrics().widthPixels; } protected int getHeightPixels(){ return getDisplayMetrics().heightPixels; } }