基础框架之BaseFragment
程序员文章站
2022-03-11 18:58:52
package iptv.com.quick.module.base;import android.content.Context;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import com.tr...
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.trello.rxlifecycle2.LifecycleTransformer;
import com.trello.rxlifecycle2.components.support.RxFragment;
import java.util.Iterator;
import javax.inject.Inject;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import iptv.com.quick.LocalApplication;
import iptv.com.quick.R;
import iptv.com.quick.injector.components.ApplicationComponent;
import iptv.com.quick.utils.Logger;
import iptv.com.quick.widget.EmptyLayout;
public abstract class BaseFragment<T extends IBasePresenter> extends RxFragment implements IBaseView, EmptyLayout.OnRetryListener, Handler.Callback {
/**
* 把 EmptyLayout 放在基类统一处理,@Nullable 表明 View 可以为 null,详细可看 ButterKnife
* 注意,资源的ID一定要一样
*/
@Nullable
@BindView(R.id.empty_layout)
protected EmptyLayout mEmptyLayout;
/**
* 把 Presenter 提取到基类需要配合基类的 initInjector() 进行注入,如果继承这个基类则必定要提供一个 Presenter 注入方法,
* 该APP所有 Presenter 都是在 Module 提供注入实现,也可以选择提供另外不带 Presenter 的基类
*/
@Inject
protected T mPresenter;
protected Context mContext;
protected View mRootView;
private Unbinder mUnbinder;
private boolean mIsFinished = false;
/**
* 当Presenter 调用 showNetError();Fragment已经被销毁,mEmptyLayout mSwipeRefresh == null
* 通过设置标记,当 onCreateView 重新设置上
*/
private boolean isNeedLaterShowNetError = false;
private boolean isNeedLaterHideLoading = false;
private String mErrormsg;
/**
* 绑定布局文件
*
* @return 布局文件Id
*/
protected abstract int attachLayoutRes();
/**
* Dagger 注入
*/
protected abstract void initInjector();
/**
* 初始化视图控件
*
* @param savedInstanceState
*/
protected abstract void initViews(Bundle savedInstanceState);
/**
* 更新视图控件
*
* @param isRefresh
*/
protected abstract void updateViews(boolean isRefresh);
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getContext();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (mRootView == null) {
// View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_vod_sub_sort,parent, false);
mRootView = inflater.inflate(attachLayoutRes(), container, false);
mUnbinder = ButterKnife.bind(this, mRootView);
initInjector();
initViews(savedInstanceState);
}
//说明一下Fragment进行复用为什么还要又要bind,如果不进行绑定成员变量是不会受到影响的,
// 但是如果有bindClick,那么这里复用的时候click 是不会有响应的
// 所用为了保证 click 有响应,复用时再次bind,只要mRootView不变,bind的成员变量也不变,只是bind成员变量的话,做了无用功而已
if (mUnbinder == null)
mUnbinder = ButterKnife.bind(this, mRootView);
if (isNeedLaterHideLoading)
hideLoading();
if (isNeedLaterShowNetError)
showNetError(mErrormsg);
ViewGroup parent = (ViewGroup) mRootView.getParent();
if (parent != null) {
parent.removeView(mRootView);
}
return mRootView;
}
@Override
public void onResume() {
super.onResume();
Logger.i(Logger._TJ, "onResume " + getClass().getSimpleName());
}
@Override
public void onPause() {
super.onPause();
Logger.i(Logger._TJ, "onPause " + getClass().getSimpleName());
}
@Override
public void onDetach() {
super.onDetach();
Logger.i(Logger._TJ, "onDetach " + getClass().getSimpleName());
}
@Override
public void onDestroyView() {
super.onDestroyView();
Logger.i(Logger._TJ, "onDestroyView " + getClass().getSimpleName());
}
/**
* 是否拦截fragment的返回事件
* @return
*/
public boolean onBackPressed() {
Logger.d(Logger._TJ, "onBackPressed " + getClass().getSimpleName());
Iterator<Fragment> iterator = getChildFragmentManager().getFragments().iterator();
while (iterator.hasNext()) {
Fragment fragment = iterator.next();
if (fragment instanceof BaseFragment) {
if (fragment.isResumed() && ((BaseFragment) fragment).onBackPressed()) {
return true;
}
}
}
if (getChildFragmentManager().getBackStackEntryCount() > 0) {
getChildFragmentManager().popBackStack();
return true;
}
return false;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//说明:getUserVisibleHint() 默认返回值是 true,
// 如果使用FragmentPagerAdapter或者FragmentStatePagerAdapter时
// 会在Fragment添加到fragmentManager之前调用fragment.setUserVisibleHint(false);
if (getUserVisibleHint() && mRootView != null) {
perUpdateView();
}
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
Logger.i(Logger._TJ, "isVisibleToUser " + getClass().getSimpleName() + " " + isVisibleToUser);
if (isVisibleToUser && mRootView != null) {
perUpdateView();
}
}
public void perUpdateView() {
if (!mIsFinished) {
updateViews(false);
}
mIsFinished = true;
}
@Override
public void onDestroy() {
super.onDestroy();
mUnbinder.unbind();
mUnbinder = null;
if (mHandler != null) {
mHandler.removeCallbacksAndMessages(null);
}
}
@Override
public void showLoading() {
if (mEmptyLayout != null) {
mEmptyLayout.setEmptyStatus(EmptyLayout.STATUS_LOADING);
}
}
@Override
public void showLoading(int loadingIv) {
if (mEmptyLayout != null) {
mEmptyLayout.setEmptyStatus(loadingIv,EmptyLayout.STATUS_LOADING_IV);
}
}
@Override
public void hideLoading() {
if (mEmptyLayout != null) {
mEmptyLayout.hide();
isNeedLaterHideLoading = false;
return;
}
isNeedLaterHideLoading = true;
}
@Override
public void showNetError(String msg) {
if (mEmptyLayout != null) {
mEmptyLayout.setEmptyStatus(EmptyLayout.STATUS_NO_NET);
mEmptyLayout.setRetryListener(this);
isNeedLaterShowNetError = false;
return;
}
mErrormsg = msg;
isNeedLaterShowNetError = true;
}
/**
* 网络错误,重试监听
*/
@Override
public void onRetry() {
perUpdateView();
}
@Override
public <T> LifecycleTransformer<T> bindToLife() {
return this.<T>bindToLifecycle();
}
/**
* 获取 ApplicationComponent
*
* @return
*/
public ApplicationComponent getAppComponent() {
return LocalApplication.getAppComponent();
}
/************************************* - Handler-Helper - ****************************************/
private Handler mHandler;
protected final Handler handler() {
if (mHandler == null) {
mHandler = new Handler(this);
}
return mHandler;
}
protected final boolean sendEmptyMessage(int what) {
if (mHandler == null) {
mHandler = new Handler(this);
}
return mHandler.sendEmptyMessage(what);
}
protected final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
if (mHandler == null) {
mHandler = new Handler(this);
}
return mHandler.sendEmptyMessageDelayed(what, delayMillis);
}
protected final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
if (mHandler == null) {
mHandler = new Handler(this);
}
return mHandler.sendEmptyMessageAtTime(what, uptimeMillis);
}
protected final void removeMessages(int what) {
if (mHandler != null) {
mHandler.removeMessages(what);
}
}
@Override
public boolean handleMessage(Message msg) {
return false;
}
/**
* 替换 Fragment
*
* @param containerViewId
* @param fragment
*/
public void replaceFragment(int containerViewId, Fragment fragment) {
FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
fragmentTransaction.replace(containerViewId, fragment);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.commit();
}
/**
* 替换 Fragment
*
* @param containerViewId
* @param fragment
* @param tag
*/
public void replaceFragment(int containerViewId, Fragment fragment, String tag) {
if (getChildFragmentManager().findFragmentByTag(tag) == null) {
FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
//设置Tag
fragmentTransaction.replace(containerViewId, fragment, tag);
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
// 这里也要设置tag,通过这里保存的tag找到对应的fragment
fragmentTransaction.addToBackStack(tag);
fragmentTransaction.commit();
Logger.d(Logger._JN, "replaceFragment :%s ", fragment.getClass().getSimpleName()+"保留上方fragment");
} else {
//存在则弹出在它上面的所有fragment,并显示对应的fragment,类似activity启动模式SingleTack
Logger.d(Logger._JN, "replaceFragment :%s ", fragment.getClass().getSimpleName()+"弹出在它上面的所有fragment");
getChildFragmentManager().popBackStackImmediate(tag, 0);
}
}
}
本文地址:https://blog.csdn.net/weixin_37716758/article/details/107985508
下一篇: java8新特性(方法引用和构造器引用)