| 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 <a href="mailto:jenly1314@gmail.com">Jenly</a> | 
|  */ | 
| public abstract class BaseDialogFragment<VM extends BaseViewModel,VDB extends ViewDataBinding> extends DialogFragment implements IView<VM>, 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 extends View> 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<VM> getVMClass(){ | 
|         Class cls = getClass(); | 
|         Class<VM> vmClass = null; | 
|         while (vmClass == null && cls!= null){ | 
|             vmClass = getVMClass(cls); | 
|             cls = cls.getSuperclass(); | 
|         } | 
|         if(vmClass == null){ | 
|             vmClass = (Class<VM>) 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<Boolean>() { | 
|             @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<Message> 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 <T> | 
|      * @return | 
|      */ | 
|     public <T extends ViewModel> T obtainViewModel(@NonNull Class<T> modelClass){ | 
|         return createViewModelProvider(this).get(modelClass); | 
|     } | 
|   | 
|     /** | 
|      * @deprecated 请使用 {@link #obtainViewModel(Class)} | 
|      * @param modelClass | 
|      * @param <T> | 
|      * @return | 
|      */ | 
|     @Deprecated | 
|     public <T extends ViewModel> T getVM(@NonNull Class<T> 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; | 
|     } | 
|   | 
| } |