AVLoadingIndicatorView 是非常炫酷的加载动画,使用起来也非常方法。今天对他进行一个封装。
1,添加依赖
//Loading 依赖 api 'com.wang.avi:library:2.1.3'
2, 设置一些加载的样式,这些在 github 上面都可以找到
public enum LoaderStyle { /** * 加载样式 */ BallPulseIndicator, BallGridPulseIndicator, BallClipRotateIndicator, BallClipRotatePulseIndicator, SquareSpinIndicator, BallClipRotateMultipleIndicator, BallPulseRiseIndicator, BallRotateIndicator, CubeTransitionIndicator, BallZigZagIndicator, BallZigZagDeflectIndicator, BallTrianglePathIndicator, BallScaleIndicator, LineScaleIndicator, LineScalePartyIndicator, BallPulseSyncIndicator, BallBeatIndicator, LineScalePulseOutIndicator, LineScalePulseOutRapidIndicator, BallScaleRippleIndicator, BallScaleRippleMultipleIndicator, BallSpinFadeLoaderIndicator, LineSpinFadeLoaderIndicator, TriangleSkewSpinIndicator, PacmanIndicator, BallGridBeatIndicator, SemiCircleSpinIndicator }
3, 通过反射获取到 需要使用 加载动画
public class LoaderCreator { //进行缓存 private static final WeakHashMap<String,Indicator> LOADING_MAP = new WeakHashMap<>(); static AVLoadingIndicatorView creawte(String type, Context context){ final AVLoadingIndicatorView avLoadingIndicatorView = new AVLoadingIndicatorView(context); if (LOADING_MAP.get(type) == null){ //根据传入的 type 进行反射 获取动画 final Indicator indicator = getIndicator(type); LOADING_MAP.put(type,indicator); } //设置 这个动画 avLoadingIndicatorView.setIndicator(LOADING_MAP.get(type)); return avLoadingIndicatorView; } private static Indicator getIndicator(String name){ if (name == null || name.isEmpty()){ return null; } final StringBuilder drawbleClassName = new StringBuilder(); //如果类名不包含 . 就说明传入的是一个 整个的类名,否则就是包名 if (!name.contains(".")){ // 拼装一个完整的路径,这个路径就是 动画类所在的位置。 final String defultPackageName = AVLoadingIndicatorView.class.getPackage().getName(); drawbleClassName.append(defultPackageName) .append(".indicators") .append("."); } drawbleClassName.append(name); try { //通过反射 拿到给定的类 final Class<?> drawableClass = Class.forName(drawbleClassName.toString()); //创建 该对象并返回 return (Indicator) drawableClass.newInstance(); } catch (Exception e) { e.printStackTrace(); return null; } } }
4,设置样式。我们要将loading 显示在 dialog 上面,在style.xml 中添加如下代码:
<resources> <style name="dialog" parent="@android:style/Theme.Dialog"> <!--去掉边框--> <item name="android:windowFrame">@null</item> <!--悬浮--> <item name="android:windowIsFloating">true</item> <!--半透明--> <item name="android:windowIsTranslucent">false</item> <!--不需要标题--> <item name="android:windowNoTitle">true</item> <!--背景透明--> <item name="android:windowBackground">@android:color/transparent</item> <!--允许模糊--> <item name="android:backgroundDimEnabled">true</item> <!--全屏幕--> <item name="android:windowFullscreen">true</item> </style> </resources>
5,创建 一个测量的类。用于适应屏幕
public class DimenUtil { /** * @return 可用显示大小的绝对宽度(以像素为单位) */ public static int getScreenWidth(){ //这里的 getAppContext 是获取Context final Resources resources = Coke.getAppContext().getResources(); final DisplayMetrics dm = resources.getDisplayMetrics(); return dm.widthPixels; } /** * @return 可用显示大小的绝对高度(以像素为单位) */ public static int getScreenHeight(){ final Resources resources = Coke.getAppContext().getResources(); final DisplayMetrics dm = resources.getDisplayMetrics(); return dm.heightPixels; } }
5, 最后一步,设置 AVLoading
public class CokeLoading { //缩放比,让load根据屏幕的大小 来调整大小。 private static final int LOADER_SIZE_SCALE = 8; //屏幕的偏移量 private static final int LOADER_OFFSET_SCALT = 10; private static final ArrayList<AppCompatDialog> LOADERS = new ArrayList<>(); private static final String DEFULT_LOADER = LoaderStyle.BallClipRotatePulseIndicator.name(); public static void showLoading(Context context, Enum<LoaderStyle> type) { showLoading(context, type.name()); } public static void showLoading(Context context, String type) { // 使用 dialog 来承载 Loading . // 尽量 使用 v7包下的东西,这样兼容性比较好 final AppCompatDialog dialog = new AppCompatDialog(context, R.style.dialog); //通过creawte方法 设置 样式 并返回对象 final AVLoadingIndicatorView avLoadingIndicatorView = LoaderCreator.creawte(type, context); dialog.setContentView(avLoadingIndicatorView); int deviceWidth = DimenUtil.getScreenWidth(); int deviceHeight = DimenUtil.getScreenHeight(); final Window dialogWindow = dialog.getWindow(); if (dialogWindow != null) { //设置 dialog 的属性 final WindowManager.LayoutParams lp = dialogWindow.getAttributes(); lp.alpha = 0.4f; lp.width = deviceWidth / LOADER_SIZE_SCALE; lp.height = deviceHeight / LOADER_SIZE_SCALE; //偏移量,会将上面的 height 个给覆盖掉 lp.height = lp.height + deviceHeight / LOADER_OFFSET_SCALT; lp.gravity = Gravity.CENTER; } LOADERS.add(dialog); dialog.show(); } public static void showLoading(Context context) { //自定义 一个默认的 加载动画 showLoading(context, DEFULT_LOADER); } public static void stopLoading() { for (AppCompatDialog dialog : LOADERS) { if (dialog != null) { if (dialog.isShowing()) { // dismiss() 只是单纯的消失掉 dialog 而 cancel 会有一些回调,所以使用cancel dialog.cancel(); } } } } }
7,使用如下:
//使用 指定的动画 CokeLoading.showLoading(getContext(),LoaderStyle.SemiCircleSpinIndicator); //使用默认的 CokeLoading.showLoading(getContext()); //关闭如下 CokeLoading.stopLoading();
效果如下:
到这里就已经封装完成了。是不是使用起来非常 方便呢。赶紧试一试吧