美文网首页
Loading 图

Loading 图

作者: 夜沐下的星雨 | 来源:发表于2020-08-05 08:03 被阅读0次

创建接口:

/用于loading
public interface BaseView {



    //显示  透明背景
    default void showPopLoading() {
        showLoading(MvpLoadingView.MODE_POP,false);
    }

    default void showPopLoading(boolean isEnableBackCancel) {

        showLoading(MvpLoadingView.MODE_POP,isEnableBackCancel);
    }
    //显示  不透明背景
    default void showFullLoading() {
        showLoading(MvpLoadingView.MODE_FULL,false);
    }
    default void showFullLoading(boolean isEnableBackCancel) {
        showLoading(MvpLoadingView.MODE_FULL,isEnableBackCancel);
    }
    default void closeLoading() {
        getLoadingView().closeLoading();
    }
    //显示错误
    default void onError() {
        getLoadingView().onError();
    }
    default void onError(MvpLoadingView.OnRetryCallBack onRetryCallBack) {
        getLoadingView().onError(onRetryCallBack);
    }
    default void onError(String message, MvpLoadingView.OnRetryCallBack callBack) {
        getLoadingView().onError(message,callBack);
    }
    //
    default void showLoading(@MvpLoadingView.loadingMode int mode,boolean isEnableBackCancel) {
        MvpLoadingView loadingView = MvpLoadingView.inject(getDefaultLoadingParent());
        loadingView.setEnableBackCancel(isEnableBackCancel);

        if(isEnableBackCancel){
            //接口
            loadingView.setCancelCallBack(new MvpLoadingView.OnCancelCallBack() {
                @Override
                public void onCancel() {
                    if(getPresenter() != null){
                        getPresenter().cancelRequest();
                    }

                }
            });
        }
        //
        setLoadView(loadingView);
        loadingView.showLoading(mode);
    }

    //获取fragment 或 activity 的viewGroup
    default ViewGroup getDefaultLoadingParent() {
        if (this instanceof BaseMVPActivity) {
            return (ViewGroup) findViewById(android.R.id.content);
        } else if (this instanceof BaseMVPFragment) {
            return (ViewGroup) ((BaseMVPFragment) this).getView();
        }
        return null;
    }
    //findViewById
    <T extends View> T findViewById(@IdRes int id);

    //获取MvpLoadingView的对象
    void setLoadView(MvpLoadingView loadView);
    //getLoadingView
    MvpLoadingView getLoadingView();
    //的presenter 的接口
    IBasePresenter getPresenter();

}
//简单版  并且没有网络切断
/*
    //显示 没背景loading
    default void showPopLoading(){
        showLoading(MvpLoadingView.MODE_POP);
    }

    //显示 有背景loading
    default void showFullLoading(){
        showLoading(MvpLoadingView.MODE_FULL);
    }
    //清除loading
    default void closeLoading(){
        getLoadingView().closeLoading();
    }
    //错误页面
    default void onError(){
        getLoadingView().onError();
    }
    //得到所需要的条件显示loading
    default void showLoading(@MvpLoadingView.loadingMode int mode){
        MvpLoadingView loadingView = MvpLoadingView.inject(getDefaultLoadingParent());
        //添加MvpLoadingView 对象
        setLoadView(loadingView);
        loadingView.showLoading(mode);

    }
    //判断当前的view 是fragment还是Activity  的到viewGroup
    default ViewGroup getDefaultLoadingParent(){
        if (this instanceof BaseMVPActivity){
        return (ViewGroup)findViewById(android.R.id.content);
        }else if (this instanceof BaseMVPFragment){
        return (ViewGroup)((BaseMVPFragment)this).getView();
        }
        return null;
    }
    //获取findViewById
    <T extends View> T findViewById(@IdRes int id);

    //得到Mvploadingview 的对象
    void setLoadView(MvpLoadingView loadView);
    //通过get 在mvp调用MvpLoadingview 的方法
    MvpLoadingView getLoadingView();
*/

MvpLoadingView - Loading工具类


public class MvpLoadingView extends ConstraintLayout {
    public static final int MODE_POP=1;
    public static final int MODE_FULL=2;
    private static final int MODE_ERROR= 3;// 错误

    private ImageView mGifBackgroundView;
    private GifView mGifView;
    private TextView mTextErrorView;
    private ImageView mImageErrorView;
    private Button mButtonErrorView;
    private Group mGroup;

    private int mCurrentMode;
    private int mPreMode;

    private ViewGroup mParent;
    private OnRetryCallBack mRetryCallBack;
    private OnCancelCallBack mCancelCallBack;

    private boolean isEnableBackCancel; // 按返回键是否支持关闭 loading

    @Retention(RetentionPolicy.SOURCE)//只在来源有用
    @IntDef({MODE_POP,MODE_FULL})//注解只能用你定义好的这两个
    public @interface loadingMode{}//定义一个loadingMode de接口并且会提醒你添加上面两个参数
    public MvpLoadingView(Context context) {
        super(context);
    }

    public MvpLoadingView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MvpLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    //获取控件,不能写在构造方法中
    //当加载完成layout_loading_view .xml 后,才会执行这个方法


    @SuppressLint("ResourceType")
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        setId(100);
        mGifBackgroundView=findViewById(R.id.mvp_loading_iv_gif_bg_view);
        mGifView=findViewById(R.id.mvp_loading_gif_view);
        mGifView.setGifResource(R.drawable.mvp_loading);
        mTextErrorView=findViewById(R.id.mvp_loading_tv_error_content);
        mImageErrorView=findViewById(R.id.mvp_loading_iv_error_icon);
        mButtonErrorView=findViewById(R.id.mvp_loading_btn_retry);
        mGroup=findViewById(R.id.mvp_loading_group_error);
        //重新加载的监听   使用mRetryCallBack 的接口回调   如果成功就 显示loading
        mButtonErrorView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mRetryCallBack != null){
                    mRetryCallBack.onRetry();
                    showLoading(mPreMode);
                }
            }
        });
        //聚焦在屏幕触摸模式下
        setFocusableInTouchMode(true);
        //请关注
        requestFocus();
        //监听返回键
        setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                // 如果支持网络取消,那么关闭自己
                // 如果不支持,不拦截
                if (isEnableBackCancel) {
                    if (mCancelCallBack != null) {
                        mCancelCallBack.onCancel(); // 回到外面调用者去取消网络请求
                    }
                    closeLoading();
                    return true;
                } else {
                    return false;
                }
            }
        });
    }
    public void setEnableBackCancel(boolean enableBackCancel) {
        isEnableBackCancel = enableBackCancel;
    }

    public void setCancelCallBack(OnCancelCallBack cancelCallBack) {
        this.mCancelCallBack = cancelCallBack;
    }
    //使用事件分发 的事件消费 点击无效
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return false;
    }
  //将自己添加到父容器里,要知道父容器的名字  FrameLayout ....
    public void setParentContainer(ViewGroup parent){
        mParent=parent;
    }
    public static MvpLoadingView inject(ViewGroup parent){
        //为了避免重复添加,那么判断一下传进来的parent 上是否已经添加了loading view
        //getChildCount    判断view的子view的个数
       /* View child;
        for (int i = 0; i < parent.getChildCount(); i++) {
            child = parent.getChildAt(i);
            if (child instanceof MvpLoadingView){
                return (MvpLoadingView) child;
            }
        }*/
        //以倒叙 的形式 减少了判断
        View child;
        for (int i = parent.getChildCount() - 1; i >= 0; i--) {
            child = parent.getChildAt(i);
            if (child instanceof MvpLoadingView) {
                return (MvpLoadingView) child;
            }
        }
        //充气布局 得到mvp
        MvpLoadingView mvpLoadingView = (MvpLoadingView) LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_loading_view, parent, false);
        //将自己添加到父布局
        mvpLoadingView.setParentContainer(parent);
        return mvpLoadingView;
    }
    //显示loading
    public void showLoading(@loadingMode int mode){
        //判断是否添加到该父容器   如果没有==null,就不重新addView
        if (this.getParent()==null){
            //获取父布局的容器名 比如 RelativeLayout,FrameLayout  ConstraintLayout
            String name = mParent.getClass().getName();
            if (name.equals(RelativeLayout.class.getName())|| name.equals(FrameLayout.class.getName())||name.equals(ContentFrameLayout.class.getName())){
                //将自己添加到全充满的视图中
                mParent.addView(this,new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
            }else if (mParent instanceof ConstraintLayout){
                mParent.addView(this);
                //得到约束集
                ConstraintSet constraintSet = new ConstraintSet();
                //clone方法你可以这么理解:
                //比如你的父布局是ConstraintLayout,名为rootLayout下有若干控件,而你只需动态修改一个TextView的相对位置或者尺寸,那么你就要先set.clone(rootLayout);等于copy了整个布局的控件与属性,然后做下面的事情。。。
                constraintSet.clone((ConstraintLayout) mParent);//clone 克隆的意思 克隆下loading层的约束布局
                constraintSet.connect(getId(),ConstraintSet.LEFT,ConstraintSet.PARENT_ID,ConstraintSet.LEFT);//connect 有四个参数: 自己的id ,从左 到克隆loading约束布局 的id 左
                constraintSet.connect(getId(),ConstraintSet.TOP,ConstraintSet.PARENT_ID,ConstraintSet.TOP);//connect 有四个参数: 自己的id ,从上 到克隆loading约束布局 的id 上
                constraintSet.connect(getId(),ConstraintSet.RIGHT,ConstraintSet.PARENT_ID,ConstraintSet.RIGHT);//connect 有四个参数: 自己的id ,从右 到克隆loading约束布局 的id 右
                constraintSet.connect(getId(),ConstraintSet.BOTTOM,ConstraintSet.PARENT_ID,ConstraintSet.BASELINE);//connect 有四个参数: 自己的id ,从下 到克隆loading约束布局 的id 下
                //apply一下使设置生效
                constraintSet.applyTo((ConstraintLayout) mParent);
            }
        }
        //用来排队显示  的效果不同 如果
        if(mCurrentMode == mode){
            return;
        }
        mPreMode = mCurrentMode;

        mCurrentMode = mode;

        //隐藏
        mGroup.setVisibility(GONE);
        if (mode==MODE_POP){
            //背景为透明
            setBackgroundColor(Color.TRANSPARENT);
            //image  显示
            mGifBackgroundView.setVisibility(VISIBLE);
        }else {
            //背景为白色
            setBackgroundColor(Color.WHITE);
            //image  隐藏
            mGifBackgroundView.setVisibility(GONE);
        }
        mGifView.setVisibility(VISIBLE);
        mGifView.play();
    }

    public void onError(){
        onError(getContext().getString(R.string.text_error_default),null);
    }

    public void onError(OnRetryCallBack onRetryCallBack){
        onError(getContext().getString(R.string.text_error_default),onRetryCallBack);
    }

    public void onError(String errMessage,OnRetryCallBack onRetryCallBack){

        mRetryCallBack = onRetryCallBack;
        mGifView.pause();
        mGifView.setVisibility(GONE);
        mGifBackgroundView.setVisibility(GONE);

        mGroup.setVisibility(VISIBLE);

        if(mCurrentMode != MODE_FULL){
            setBackgroundColor(Color.WHITE);
        }
        mTextErrorView.setText(errMessage);
        mButtonErrorView.setVisibility(mRetryCallBack == null ? GONE : VISIBLE);

        mPreMode = mCurrentMode;

        mCurrentMode = MODE_ERROR;
    }
    /**
     * 第一中出错误
     */
    public void closeLoading(){
        if (mParent!=null){
            //清除
            mParent.removeView(this);
        }
    }


    public interface OnRetryCallBack{
        void onRetry();
    }
    public interface OnCancelCallBack{
        void onCancel();
    }

}

相关文章

网友评论

      本文标题:Loading 图

      本文链接:https://www.haomeiwen.com/subject/izimrktx.html