美文网首页
自定义载入页 - LoadingView

自定义载入页 - LoadingView

作者: 魔女小姐的猫 | 来源:发表于2020-08-26 01:09 被阅读0次

    依赖

    implementation 'com.github.Cutta:GifView:1.4' //在项目中buildscript下添加  maven { url 'https://jitpack.io' }
    

    xml布局

    <?xml version="1.0" encoding="utf-8"?>
    <com.m.k.seetaoism.widgets.MvpLoadingView xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:app="http://schemas.android.com/apk/res-auto"
       xmlns:tools="http://schemas.android.com/tools"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
    
    
       <ImageView
           android:id="@+id/mvp_loading_iv_gif_bg_view"
           android:layout_width="100dp"
           android:layout_height="100dp"
           android:background="@drawable/mvp_loading_bg"
           android:elevation="24dp"
           app:layout_constraintBottom_toBottomOf="parent"
           app:layout_constraintEnd_toEndOf="parent"
           app:layout_constraintStart_toStartOf="parent"
           app:layout_constraintTop_toTopOf="parent" />
    
       <com.cunoraz.gifview.library.GifView
           android:id="@+id/mvp_loading_gif_view"
           android:layout_width="90dp"
           android:layout_height="90dp"
           android:elevation="18dp"
           app:gif="@drawable/mvp_loading"
           app:layout_constraintBottom_toBottomOf="parent"
           app:layout_constraintEnd_toEndOf="parent"
           app:layout_constraintStart_toStartOf="parent"
           app:layout_constraintTop_toTopOf="parent" />
    
    
       <TextView
           android:id="@+id/mvp_loading_tv_error_content"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           app:layout_constraintBottom_toBottomOf="parent"
           app:layout_constraintEnd_toEndOf="parent"
           app:layout_constraintStart_toStartOf="parent"
           app:layout_constraintTop_toTopOf="parent"
           android:text="加载失败,请重试" />
    
       <Button
           android:id="@+id/mvp_loading_btn_retry"
           android:layout_width="0dp"
           android:layout_height="wrap_content"
           android:layout_marginStart="64dp"
           android:layout_marginTop="24dp"
           android:layout_marginEnd="64dp"
           android:background="@drawable/mvp_loading_retry_button_bg_selector"
           android:text="点击重试"
           app:layout_constraintEnd_toEndOf="parent"
           app:layout_constraintStart_toStartOf="parent"
           app:layout_constraintTop_toBottomOf="@+id/mvp_loading_gif_view" />
    
       <ImageView
           android:id="@+id/mvp_loading_iv_error_icon"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_marginBottom="24dp"
           android:background="@drawable/mvp_loging_error"
           app:layout_constraintBottom_toTopOf="@+id/mvp_loading_gif_view"
           app:layout_constraintEnd_toEndOf="parent"
           app:layout_constraintHorizontal_bias="0.493"
           app:layout_constraintStart_toStartOf="parent" />
    
       <androidx.constraintlayout.widget.Group
           android:id="@+id/mvp_loading_group_error"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:visibility="gone"
           app:constraint_referenced_ids="mvp_loading_tv_error_content,mvp_loading_btn_retry,mvp_loading_iv_error_icon" />
    
    
    </com.m.k.seetaoism.widgets.MvpLoadingView>
    

    mvp_loading_retry_button_bg_selector

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true">
            <shape android:layout_width="match_parent" android:layout_height="match_parent" android:shape="rectangle">
                <corners android:radius="20dp" />
                <stroke android:width="1dp" android:color="#ffffff" />
                <solid android:color="#dbdbdb" />
            </shape>
    
        </item>
        <item>
            <shape android:shape="rectangle">
                <corners android:radius="20dp"/>
                <stroke android:color="#dbdbdb" android:width="1dp"/>
                <solid android:color="#ffffff"/>
            </shape>
        </item>
    
    </selector>
    

    MvpLoadingView 类

    package com.example.loadinglib;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.graphics.Color;
    import android.util.AttributeSet;
    import android.view.KeyEvent;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.FrameLayout;
    import android.widget.ImageView;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    
    import androidx.annotation.IntDef;
    import androidx.appcompat.widget.ContentFrameLayout;
    import androidx.constraintlayout.widget.ConstraintLayout;
    import androidx.constraintlayout.widget.ConstraintSet;
    import androidx.constraintlayout.widget.Group;
    
    
    import com.cunoraz.gifview.library.GifView;
    
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    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 Group mErrorPage;
        private ImageView mErrorIcon;
        private TextView mErrorMessage;
        private Button mRetry;
    
        private ViewGroup mParent;
    
        private OnRetryCallBack mRetryCallBack;
        private OnCancelCallBack mCancelCallBack;
    
        private int mCurrentMode;
        private int mPreMode;
    
        private boolean isEnableBackCancel; // 按返回键是否支持关闭 loading
    
        @Retention(RetentionPolicy.SOURCE)
        @IntDef({MODE_POP, MODE_FULL})
        public @interface LoadingMode {
        }
    
    
        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);
        }
    
        @SuppressLint("ResourceType")
        @Override
        protected void onFinishInflate() {
            super.onFinishInflate();
            setId(10000);
            mGifBackgroundView = findViewById(R.id.mvp_loading_iv_gif_bg_view);
            mGifView = findViewById(R.id.mvp_loading_gif_view);
            mErrorPage = findViewById(R.id.mvp_loading_group_error);
            mErrorIcon = findViewById(R.id.mvp_loading_iv_error_icon);
            mErrorMessage = findViewById(R.id.mvp_loading_tv_error_content);
            mRetry = findViewById(R.id.mvp_loading_btn_retry);
    
    
            mRetry.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(mRetryCallBack != null){
                        mRetryCallBack.onRetry();
                        showLoading(mPreMode);
                    }
                }
            });
            setFocusableInTouchMode(true);
            requestFocus();
            setOnKeyListener(new View.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;
        }
    
        public void setParentContainer(ViewGroup parent) {
            mParent = parent;
        }
    
    
        public static MvpLoadingView inject(ViewGroup parent) {
    
            // 为了避免重复添加,那么判断一下传进来的 parent 上是否已经添加了loading view
    
    
            View child;
            for (int i = parent.getChildCount() - 1; i >= 0; i--) {
                child = parent.getChildAt(i);
                if (child instanceof MvpLoadingView) {
                    return (MvpLoadingView) child;
                }
            }
    
    
            MvpLoadingView loadingView = (MvpLoadingView) LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_loading_view, parent, false);
    
            loadingView.setParentContainer(parent);
    
            return loadingView;
        }
    
        public void showLoading(@LoadingMode int mode) {
    
            if (this.getParent() == null) {
    
                String parentClassName = mParent.getClass().getName();
                if (parentClassName.equals(RelativeLayout.class.getName()) || parentClassName.equals(FrameLayout.class.getName()) || parentClassName.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();
                    constraintSet.clone((ConstraintLayout) mParent);
    
                    constraintSet.connect(getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START);
                    constraintSet.connect(getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP);
                    constraintSet.connect(getId(), ConstraintSet.END, mParent.getId(), ConstraintSet.END);
                    constraintSet.connect(getId(), ConstraintSet.BOTTOM, mParent.getId(), ConstraintSet.BOTTOM);
                    constraintSet.applyTo((ConstraintLayout) mParent);
    
    
                }
            }
    
    
    
            if(mCurrentMode == mode){
                return;
            }
    
    
            mPreMode = mCurrentMode;
    
            mCurrentMode = mode;
    
            mErrorPage.setVisibility(GONE);
            if (mode == MODE_POP) {
                setBackgroundColor(Color.TRANSPARENT);
                mGifBackgroundView.setVisibility(VISIBLE);
            } else {
                setBackgroundColor(Color.WHITE);
                mGifBackgroundView.setVisibility(GONE);
            }
            mGifView.setVisibility(VISIBLE);
            mGifView.play();
    
    }
    
        public void onError(){
            onError("加载失败,请重试",null);
        }
    
        public void onError(OnRetryCallBack onRetryCallBack){
            onError("加载失败,请重试",onRetryCallBack);
        }
    
        public void onError(String errMessage,OnRetryCallBack onRetryCallBack){
    
            mRetryCallBack = onRetryCallBack;
            mGifView.pause();
            mGifView.setVisibility(GONE);
            mGifBackgroundView.setVisibility(GONE);
    
            mErrorPage.setVisibility(VISIBLE);
    
            if(mCurrentMode != MODE_FULL){
                setBackgroundColor(Color.WHITE);
            }
            mErrorMessage.setText(errMessage);
            mRetry.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();
        }
    }
    
    

    相关文章

      网友评论

          本文标题:自定义载入页 - LoadingView

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