Android 仿IOS加载框
2020-05-22 本文已影响0人
因为我的心
一、前言:
在公司UI设计的时候,经常以苹果的UI设计为主,我们Android们就要自定义实现苹果加载框的样式。
gitee地址:https://gitee.com/luoyanyong/LodingWindowDemo
效果图如下:
二、 jar包实现仿IOS样式:
1、项目下的build.gradle添加
allprojects {
repositories {
...
maven { url 'https://www.jitpack.io' }
}
}
2、模块下的build.gradle添加依赖
dependencies {
compile 'com.github.gittjy:LoadingDialog:1.0.2'
}
3、在代码中使用
LoadingDailog.Builder loadBuilder=new LoadingDailog.Builder(this)
.setMessage("加载中...")
.setCancelable(true)
.setCancelOutside(true);
LoadingDailog dialog=loadBuilder.create();
dialog.show();
三、自定义实现苹果样式:
1. CustomerLoadingDailog.java
package com.sumansoul.lodingwindowdemo.utils;
import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import com.sumansoul.lodingwindowdemo.R;
/**
* Created by tjy on 2017/6/19.
*/
public class CustomerLoadingDailog extends Dialog {
public CustomerLoadingDailog(Context context) {
super(context);
}
public CustomerLoadingDailog(Context context, int themeResId) {
super(context, themeResId);
}
public static class Builder {
private Context context;
private String message;
private boolean isShowMessage = true;
private boolean isCancelable = false;
private boolean isCancelOutside = false;
public Builder(Context context) {
this.context = context;
}
/**
* 设置提示信息
*
* @param message
* @return
*/
public Builder setMessage(String message) {
this.message = message;
return this;
}
/**
* 设置是否显示提示信息
*
* @param isShowMessage
* @return
*/
public Builder setShowMessage(boolean isShowMessage) {
this.isShowMessage = isShowMessage;
return this;
}
/**
* 设置是否可以按返回键取消
*
* @param isCancelable
* @return
*/
public Builder setCancelable(boolean isCancelable) {
this.isCancelable = isCancelable;
return this;
}
/**
* 设置是否可以取消
*
* @param isCancelOutside
* @return
*/
public Builder setCancelOutside(boolean isCancelOutside) {
this.isCancelOutside = isCancelOutside;
return this;
}
public CustomerLoadingDailog create() {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.dialog_loading, null);
CustomerLoadingDailog loadingDailog = new CustomerLoadingDailog(context, R.style.IosDialogStyle);
TextView msgText = (TextView) view.findViewById(R.id.tipTextView);
if (isShowMessage) {
msgText.setText(message);
} else {
msgText.setVisibility(View.GONE);
}
loadingDailog.setContentView(view);
loadingDailog.setCancelable(isCancelable);
loadingDailog.setCanceledOnTouchOutside(isCancelOutside);
return loadingDailog;
}
}
}
2. dialog_loading.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialog_loading_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="150dp"
android:layout_height="110dp"
android:background="@drawable/loading_bg"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingLeft="21dp"
android:paddingRight="21dp"
android:paddingTop="10dp">
<ProgressBar
android:id="@+id/progressBar1"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_gravity="center_horizontal"
android:indeterminateBehavior="repeat"
android:indeterminateDrawable="@drawable/dialog_loading"
android:indeterminateOnly="true" />
<TextView
android:id="@+id/tipTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="加载中..."
android:textColor="#f0f0f0"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
3. style.xml
<!-- 仿IOS加载框 -->
<style name="IosDialogStyle">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
4. dialog_loading.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@mipmap/dialog_loading_img"
android:pivotX="50%"
android:pivotY="50%" />
<!-- 下面是转圈的
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/dialog_loading_img2"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
-->
5. 调用:
/**
* 2.自定义加载框
*/
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CustomerLoadingDailog.Builder loadBuilder=new CustomerLoadingDailog.Builder(MainActivity.this)
.setMessage("正在加载中...")
.setCancelable(true)
.setCancelOutside(false);
CustomerLoadingDailog dialog=loadBuilder.create();
dialog.show();
}
});
四、Android原生仿闪屏:
闪屏原理:https://www.jianshu.com/p/77b09c686e3d
1. 调用
/**
* 3.Android原生加载框(防止闪屏)
*/
btn3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final AlertLoadingDialog dialog = new AlertLoadingDialog(MainActivity.this);
dialog.showDialog("努力加载中...");
dialog.setCanceledOnTouchOutside(false);
//sleep设置的是时长
//sleep设置的是时长
// new Handler().postDelayed(new Runnable() {
// @Override
// public void run() {
// dialog.hideDialog();
// }
// },1000) ;
}
});
2. AlertLoadingDialog.java
/**
* 防止闪屏
*/
public class AlertLoadingDialog extends AlertDialog {
private static final int MIN_SHOW_TIME = 300;
private static final int MIN_DELAY = 300;
private TextView tvMessage;
private long mStartTime = -1;
private boolean mPostedHide = false;
private boolean mPostedShow = false;
private boolean mDismissed = false;
private Handler mHandler = new Handler();
private final Runnable mDelayedHide = new Runnable() {
@Override
public void run() {
mPostedHide = false;
mStartTime = -1;
dismiss();
}
};
private final Runnable mDelayedShow = new Runnable() {
@Override
public void run() {
mPostedShow = false;
if (!mDismissed) {
mStartTime = System.currentTimeMillis();
show();
}
}
};
public AlertLoadingDialog(@NonNull Context context) {
super(context, R.style.IosDialogStyle);
View loadView = LayoutInflater.from(getContext()).inflate(R.layout.alert_dialog_loading, null);
setView(loadView);
tvMessage = loadView.findViewById(R.id.tv_message);
}
public void showDialog() {
// tvMessage.setText(message);
mStartTime = -1;
mDismissed = false;
mHandler.removeCallbacks(mDelayedHide);
mPostedHide = false;
if (!mPostedShow) {
mHandler.postDelayed(mDelayedShow, MIN_DELAY);
mPostedShow = true;
}
}
public void showDialog(String message) {
tvMessage.setText(message);
mStartTime = -1;
mDismissed = false;
mHandler.removeCallbacks(mDelayedHide);
mPostedHide = false;
if (!mPostedShow) {
mHandler.postDelayed(mDelayedShow, MIN_DELAY);
mPostedShow = true;
}
}
public void hideDialog() {
mDismissed = true;
mHandler.removeCallbacks(mDelayedShow);
mPostedShow = false;
long diff = System.currentTimeMillis() - mStartTime;
if (diff >= MIN_SHOW_TIME || mStartTime == -1) {
dismiss();
} else {
if (!mPostedHide) {
mHandler.postDelayed(mDelayedHide, MIN_SHOW_TIME - diff);
mPostedHide = true;
}
}
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
mHandler.removeCallbacks(mDelayedHide);
mHandler.removeCallbacks(mDelayedShow);
}
}
3.alert_dialog_loading.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="20dp"
android:background="@drawable/round_ffffff_8"
>
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="@color/colorPrimary"
/>
<TextView
android:id="@+id/tv_message"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在努力加载中..."
android:textColor="#333333"
android:textSize="16sp"
/>
</LinearLayout>
4.style.xml
<!-- 仿IOS加载框 -->
<style name="IosDialogStyle">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
五、Android引入加载动画:
效果图:
6666.gif原生Demo:https://github.com/ybq/Android-SpinKit
1. 依赖
dependencies {
implementation 'com.github.ybq:Android-SpinKit:1.4.0'
}
2. Xml
<com.github.ybq.android.spinkit.SpinKitView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/spin_kit"
style="@style/SpinKitView.Large.Circle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:SpinKit_Color="@color/colorAccent" />
3. ProgressBar
ProgressBar progressBar = (ProgressBar)findViewById(R.id.progress);
Sprite doubleBounce = new DoubleBounce();
progressBar.setIndeterminateDrawable(doubleBounce);
4. Style
@style/SpinKitView
@style/SpinKitView.Circle
@style/SpinKitView.Large
@style/SpinKitView.Small
@style/SpinKitView.Small.DoubleBounce
5.调用:
/**
* 5.Android 动画一
*/
btn5.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertAnimationLoading alertLoading1 = new AlertAnimationLoading(MainActivity.this, R.layout.base_loading_dialog);
alertLoading1.setMessage("加载中....");
alertLoading1.setCanceledOnTouchOutside(true);
alertLoading1.show();
}
});
6.AlertAnimationLoading.java
public class AlertAnimationLoading extends AlertDialog {
private static final int MIN_SHOW_TIME = 300;
private static final int MIN_DELAY = 300;
private long mStartTime = -1;
private boolean mPostedHide = false;
private boolean mPostedShow = false;
private boolean mDismissed = false;
private Handler mHandler = new Handler();
private TextView tv_tips;
private int layoutResId;
private String message;
private final Runnable mDelayedHide = new Runnable() {
@Override
public void run() {
mPostedHide = false;
mStartTime = -1;
dismiss();
}
};
private final Runnable mDelayedShow = new Runnable() {
@Override
public void run() {
mPostedShow = false;
if (!mDismissed) {
mStartTime = System.currentTimeMillis();
show();
}
}
};
public AlertAnimationLoading(@NonNull Context context, int layoutResId) {
super(context, R.style.IosDialogStyle);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.layoutResId = layoutResId;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(layoutResId);
tv_tips = (TextView) findViewById(R.id.tv_tips);
tv_tips.setText(this.message);
}
public void showDialog() {
mStartTime = -1;
mDismissed = false;
mHandler.removeCallbacks(mDelayedHide);
mPostedHide = false;
if (!mPostedShow) {
mHandler.postDelayed(mDelayedShow, MIN_DELAY);
mPostedShow = true;
}
}
public void showDialog(String message) {
tv_tips.setText(message);
mStartTime = -1;
mDismissed = false;
mHandler.removeCallbacks(mDelayedHide);
mPostedHide = false;
if (!mPostedShow) {
mHandler.postDelayed(mDelayedShow, MIN_DELAY);
mPostedShow = true;
}
}
public void hideDialog() {
mDismissed = true;
mHandler.removeCallbacks(mDelayedShow);
mPostedShow = false;
long diff = System.currentTimeMillis() - mStartTime;
if (diff >= MIN_SHOW_TIME || mStartTime == -1) {
dismiss();
} else {
if (!mPostedHide) {
mHandler.postDelayed(mDelayedHide, MIN_SHOW_TIME - diff);
mPostedHide = true;
}
}
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
mHandler.removeCallbacks(mDelayedHide);
mHandler.removeCallbacks(mDelayedShow);
}
public void setMessage(String message) {
this.message = message;
if (!TextUtils.isEmpty(message) && this.tv_tips != null) {
this.tv_tips.setText(this.message);
}
}
}
7.style.xml
<!-- 仿IOS加载框 -->
<style name="IosDialogStyle">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
8. base_loading_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="140dp"
android:layout_height="120dp"
android:background="@drawable/round_ffffff_8"
android:gravity="center"
android:orientation="vertical">
<com.github.ybq.android.spinkit.SpinKitView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/spin_kit"
style="@style/SpinKitView.Large.Circle"
android:layout_width="90dp"
android:layout_height="90dp"
android:gravity="center"
android:padding="10dp"
app:SpinKit_Color="#FF4961AC" />
<TextView
android:id="@+id/tv_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="努力加载中..."
android:textColor="#000000"
android:textSize="15sp" />
</LinearLayout>