|
|
@@ -0,0 +1,185 @@
|
|
|
+package com.miekir.mvp.view.model;
|
|
|
+
|
|
|
+import android.os.Bundle;
|
|
|
+import android.text.TextUtils;
|
|
|
+
|
|
|
+import androidx.annotation.Nullable;
|
|
|
+import androidx.lifecycle.Observer;
|
|
|
+import androidx.lifecycle.ViewModelProvider;
|
|
|
+
|
|
|
+import com.miekir.mvp.base.BaseFragment;
|
|
|
+import com.miekir.mvp.base.DataResult;
|
|
|
+import com.miekir.mvp.presenter.BaseViewModel;
|
|
|
+import com.miekir.mvp.presenter.DataMethod;
|
|
|
+import com.miekir.mvp.presenter.InjectViewModel;
|
|
|
+import com.miekir.mvp.view.IView;
|
|
|
+
|
|
|
+import java.lang.reflect.Field;
|
|
|
+import java.lang.reflect.Method;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+
|
|
|
+public abstract class BaseMVPFragment extends BaseFragment implements IView {
|
|
|
+ /**
|
|
|
+ * 是否被创建了
|
|
|
+ */
|
|
|
+ protected boolean isViewCreated;
|
|
|
+ /**
|
|
|
+ * 当前是否可见
|
|
|
+ */
|
|
|
+ protected boolean isUIVisible;
|
|
|
+
|
|
|
+ private List<Method> mDataMethodList = new ArrayList<>();
|
|
|
+ private List<BaseViewModel> mInjectPresenters;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onCreateViewFinished(@Nullable Bundle savedInstanceState) {
|
|
|
+ onViewInit();
|
|
|
+
|
|
|
+ // 查找回调方法
|
|
|
+ if (mDataMethodList.size() == 0) {
|
|
|
+ Method[] methods = null;
|
|
|
+ try {
|
|
|
+ // This is faster than getMethods, especially when subscribers are fat classes like Activities
|
|
|
+ methods = getClass().getDeclaredMethods();
|
|
|
+ } catch (Throwable th) {
|
|
|
+ // Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
|
|
|
+ try {
|
|
|
+ methods = getClass().getDeclaredMethods();
|
|
|
+ } catch (LinkageError error) { // super class of NoClassDefFoundError to be a bit more broad...
|
|
|
+ error.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (methods != null && methods.length > 0) {
|
|
|
+ for (Method method : methods) {
|
|
|
+ DataMethod dataMethod = method.getAnnotation(DataMethod.class);
|
|
|
+ if (dataMethod != null) {
|
|
|
+ mDataMethodList.add(method);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 参数校验
|
|
|
+ if (methods != null && methods.length > 0) {
|
|
|
+ for (Method method : methods) {
|
|
|
+ DataMethod dataMethod = method.getAnnotation(DataMethod.class);
|
|
|
+ if (dataMethod != null) {
|
|
|
+ int length = method.getParameterTypes().length;
|
|
|
+ if (length != 3) {
|
|
|
+ throw new AssertionError("DataMethod参数数量必须为3个");
|
|
|
+ }
|
|
|
+
|
|
|
+ String firstType = method.getParameterTypes()[0].getSimpleName();
|
|
|
+ String firstCorrectType = int.class.getSimpleName();
|
|
|
+ if (!TextUtils.equals(firstCorrectType, firstType)) {
|
|
|
+ throw new AssertionError("DataMethod第1个参数必须为" + firstCorrectType);
|
|
|
+ }
|
|
|
+
|
|
|
+ String secondType = method.getParameterTypes()[1].getSimpleName();
|
|
|
+ String secondCorrectType = String.class.getSimpleName();
|
|
|
+ if (!TextUtils.equals(secondCorrectType, secondType)) {
|
|
|
+ throw new AssertionError("DataMethod第2个参数必须为" + secondCorrectType);
|
|
|
+ }
|
|
|
+
|
|
|
+ mDataMethodList.add(method);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 这里可以获取到子类的成员变量
|
|
|
+ mInjectPresenters = new ArrayList<>();
|
|
|
+ Field[] fields = this.getClass().getDeclaredFields();
|
|
|
+ for (Field field : fields) {
|
|
|
+ //获取变量上面的注解类型
|
|
|
+ InjectViewModel injectViewModel = field.getAnnotation(InjectViewModel.class);
|
|
|
+ if (injectViewModel != null) {
|
|
|
+ try {
|
|
|
+ field.setAccessible(true);
|
|
|
+
|
|
|
+ Class<? extends BaseViewModel> type = (Class<? extends BaseViewModel>) field.getType();
|
|
|
+ //BaseViewModel presenter = type.newInstance();
|
|
|
+
|
|
|
+ //创建一个观察者去更新UI
|
|
|
+ final Observer<DataResult> observer = new Observer<DataResult>() {
|
|
|
+ @Override
|
|
|
+ public void onChanged(final DataResult result) {
|
|
|
+ onDataResult(result);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ BaseViewModel presenter = new ViewModelProvider(this).get(type);
|
|
|
+ presenter.getLiveData().observe(this, observer);
|
|
|
+
|
|
|
+ field.set(this, presenter);
|
|
|
+ mInjectPresenters.add(presenter);
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (ClassCastException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new RuntimeException("SubClass must extends Class:BaseViewModel");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ isViewCreated = true;
|
|
|
+ loadData();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * View初始化
|
|
|
+ */
|
|
|
+ protected abstract void onViewInit();
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void setUserVisibleHint(boolean isVisibleToUser) {
|
|
|
+ super.setUserVisibleHint(isVisibleToUser);
|
|
|
+ isUIVisible = isVisibleToUser;
|
|
|
+ if (isVisibleToUser) {
|
|
|
+ loadData();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 懒加载,当Fragment可见的时候,再去加载数据
|
|
|
+ * 应用初始化会先调用完所有的setUserVisibleHint再调用onViewCreated,然后切换的时候,就只调用setUserVisibleHint了
|
|
|
+ */
|
|
|
+ private void loadData() {
|
|
|
+ if (isViewCreated && isUIVisible) {
|
|
|
+ isViewCreated = false;
|
|
|
+ isUIVisible = false;
|
|
|
+ onLazyLoad();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 懒加载,初始化加载数据
|
|
|
+ */
|
|
|
+ protected abstract void onLazyLoad();
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onDestroyView() {
|
|
|
+ super.onDestroyView();
|
|
|
+ if (mInjectPresenters != null && mInjectPresenters.size() > 0) {
|
|
|
+ for (BaseViewModel presenter : mInjectPresenters) {
|
|
|
+ presenter.getLiveData().removeObservers(this);
|
|
|
+ presenter.detachView();
|
|
|
+ }
|
|
|
+ mInjectPresenters.clear();
|
|
|
+ mInjectPresenters = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ mDataMethodList.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void onDataResult(DataResult result) {
|
|
|
+ for (Method method : mDataMethodList) {
|
|
|
+ try {
|
|
|
+ method.invoke(this, result.getCode(), result.getMessage(), result.getBean());
|
|
|
+ } catch (Exception e) {
|
|
|
+ //e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|