创建接口:
/用于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();
}
}
网友评论