欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

基础框架之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