package me.jingbin.bymvvm.base; import android.app.Activity; import android.content.Context; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewStub; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.databinding.DataBindingUtil; import androidx.databinding.ViewDataBinding; import androidx.fragment.app.Fragment; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.ViewModelProvider; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; import me.jingbin.bymvvm.R; import me.jingbin.bymvvm.utils.ClassUtil; /** * 是没有title的Fragment * * @author jingbin */ public abstract class BaseFragment<VM extends AndroidViewModel, SV extends ViewDataBinding> extends Fragment { // ViewModel protected VM viewModel; // 布局view protected SV bindingView; // fragment是否显示了 protected boolean mIsVisible = false; // 加载中 private View loadingView; // 加载失败 private View errorView; // 空布局 private View emptyView; // 动画 private AnimationDrawable mAnimationDrawable; private CompositeDisposable mCompositeDisposable; private Activity activity; @Override public void onAttach(Context context) { super.onAttach(context); activity = (Activity) context; } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View inflate = inflater.inflate(R.layout.fragment_base, null); bindingView = DataBindingUtil.inflate(activity.getLayoutInflater(), setContent(), null, false); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); bindingView.getRoot().setLayoutParams(params); RelativeLayout mContainer = inflate.findViewById(R.id.container); mContainer.addView(bindingView.getRoot()); bindingView.getRoot().setVisibility(View.GONE); return inflate; } /** * 在这里实现Fragment数据的缓加载. */ @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (getUserVisibleHint()) { mIsVisible = true; onVisible(); } else { mIsVisible = false; onInvisible(); } } protected void onInvisible() { } /** * 显示时加载数据,需要这样的使用 * 注意声明 isPrepared,先初始化 * 生命周期会先执行 setUserVisibleHint 再执行onActivityCreated * 在 onActivityCreated 之后第一次显示加载数据,只加载一次 */ protected void loadData() { } protected void onVisible() { loadData(); } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); initViewModel(); } /** * 初始化ViewModel */ private void initViewModel() { Class<VM> viewModelClass = ClassUtil.getViewModel(this); if (viewModelClass != null) { this.viewModel = new ViewModelProvider(this).get(viewModelClass); } } protected <T extends View> T getView(int id) { return (T) getView().findViewById(id); } /** * 布局 */ public abstract int setContent(); /** * 加载失败后点击后的操作 */ protected void onRefresh() { } /** * 显示加载中状态 */ protected void showLoading() { ViewStub viewStub = getView(R.id.vs_loading); if (viewStub != null) { loadingView = viewStub.inflate(); ImageView img = loadingView.findViewById(R.id.img_progress); mAnimationDrawable = (AnimationDrawable) img.getDrawable(); } if (loadingView != null && loadingView.getVisibility() != View.VISIBLE) { loadingView.setVisibility(View.VISIBLE); } // 开始动画 if (mAnimationDrawable != null && !mAnimationDrawable.isRunning()) { mAnimationDrawable.start(); } if (bindingView.getRoot().getVisibility() != View.GONE) { bindingView.getRoot().setVisibility(View.GONE); } if (errorView != null) { errorView.setVisibility(View.GONE); } if (emptyView != null && emptyView.getVisibility() != View.GONE) { emptyView.setVisibility(View.GONE); } } /** * 加载完成的状态 */ protected void showContentView() { if (bindingView.getRoot().getVisibility() != View.VISIBLE) { bindingView.getRoot().setVisibility(View.VISIBLE); } if (loadingView != null && loadingView.getVisibility() != View.GONE) { loadingView.setVisibility(View.GONE); } // 停止动画 if (mAnimationDrawable != null && mAnimationDrawable.isRunning()) { mAnimationDrawable.stop(); } if (errorView != null) { errorView.setVisibility(View.GONE); } if (emptyView != null && emptyView.getVisibility() != View.GONE) { emptyView.setVisibility(View.GONE); } } /** * 加载失败点击重新加载的状态 */ protected void showError() { ViewStub viewStub = getView(R.id.vs_error_refresh); if (viewStub != null) { errorView = viewStub.inflate(); // 点击加载失败布局 errorView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showLoading(); onRefresh(); } }); } if (errorView != null) { errorView.setVisibility(View.VISIBLE); } if (loadingView != null && loadingView.getVisibility() != View.GONE) { loadingView.setVisibility(View.GONE); } // 停止动画 if (mAnimationDrawable != null && mAnimationDrawable.isRunning()) { mAnimationDrawable.stop(); } if (bindingView.getRoot().getVisibility() != View.GONE) { bindingView.getRoot().setVisibility(View.GONE); } if (emptyView != null && emptyView.getVisibility() != View.GONE) { emptyView.setVisibility(View.GONE); } } protected void showEmptyView(String text) { // 需要这样处理,否则二次显示会失败 ViewStub viewStub = getView(R.id.vs_empty); if (viewStub != null) { emptyView = viewStub.inflate(); ((TextView) emptyView.findViewById(R.id.tv_tip_empty)).setText(text); } if (emptyView != null) { emptyView.setVisibility(View.VISIBLE); } if (loadingView != null && loadingView.getVisibility() != View.GONE) { loadingView.setVisibility(View.GONE); } // 停止动画 if (mAnimationDrawable != null && mAnimationDrawable.isRunning()) { mAnimationDrawable.stop(); } if (errorView != null) { errorView.setVisibility(View.GONE); } if (bindingView != null && bindingView.getRoot().getVisibility() != View.GONE) { bindingView.getRoot().setVisibility(View.GONE); } } public void addSubscription(Disposable disposable) { if (this.mCompositeDisposable == null) { this.mCompositeDisposable = new CompositeDisposable(); } this.mCompositeDisposable.add(disposable); } @Override public void onDestroy() { super.onDestroy(); if (this.mCompositeDisposable != null && !mCompositeDisposable.isDisposed()) { this.mCompositeDisposable.clear(); } } public void removeDisposable() { if (this.mCompositeDisposable != null && !mCompositeDisposable.isDisposed()) { this.mCompositeDisposable.dispose(); } } }