一.效果1:缩放、平移、渐变、弹簧弹性动画效果

1.效果图:

android引导 android引导页动画_android

2.添加依赖:

//动画
    implementation 'com.daimajia.androidanimations:library:1.1.3@aar'
    implementation 'io.reactivex:rxandroid:1.2.0'
    implementation 'io.reactivex:rxjava:1.1.5'
    implementation 'com.jakewharton:butterknife:8.0.1'

3.主函数代码:

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;

import com.daimajia.androidanimations.library.Techniques;
import com.daimajia.androidanimations.library.YoYo;
import com.hjq.demo.R;
import com.hjq.demo.ui.activity.sgf.search.SearchviewActivity;

import java.util.concurrent.TimeUnit;

import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

/**
 * app启动动画系列
 * https://github.com/HMonkey1024/MyLauncher
 * https://github.com/darryrzhong/OpenEyes
 */
public final class SgfSplash5Activity extends AppCompatActivity {
    @BindView(R.id.logo_outer_iv)
    ImageView mLogoOuterIv;
    @BindView(R.id.logo_inner_iv)
    ImageView mLogoInnerIv;
    boolean isShowingRubberEffect = false;
    @BindView(R.id.app_name_tv)
    TextView mAppNameTv;
    private long exitTime;
    private TextView tvRegister;
    private TextView tvLogin;
    private ImageView ivLogo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //全屏
//        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_sgf_splash5);
        ButterKnife.bind(this);

        initAnimation();
    }

    private void initAnimation() {
        startLogoInner1();
        startLogoOuterAndAppName();
    }

    private void startLogoInner1() {
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_top_in);
        mLogoInnerIv.startAnimation(animation);
    }

    private void startLogoOuterAndAppName() {
        final ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
        valueAnimator.setDuration(1000);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float fraction = animation.getAnimatedFraction();
//                KLog.d("fraction: " + fraction);
                if (fraction >= 0.8 && !isShowingRubberEffect) {
                    isShowingRubberEffect = true;
                    startLogoOuter();
                    startShowAppName();
                    finishActivity();
                } else if (fraction >= 0.95) {
                    valueAnimator.cancel();
                    startLogoInner2();
                }

            }
        });
        valueAnimator.start();
    }

    private void startLogoOuter() {
        YoYo.with(Techniques.RubberBand).duration(1000).playOn(mLogoOuterIv);
    }

    private void startShowAppName() {
        YoYo.with(Techniques.FadeIn).duration(1000).playOn(mAppNameTv);
    }

    private void startLogoInner2() {
        YoYo.with(Techniques.Bounce).duration(1000).playOn(mLogoInnerIv);
    }

    private void finishActivity() {
        Observable.timer(1000, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        startActivity(new Intent(SgfSplash5Activity.this, SearchviewActivity.class));
                        overridePendingTransition(0, android.R.anim.fade_out);
                        finish();
                    }
                });
    }
}

4.布局代码:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/wallpaper_12"
    tools:context=".ui.activity.sgf.guide.SgfSplash5Activity">

    <ImageView
        android:id="@+id/logo_outer_iv"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher_outer"/>

    <ImageView
        android:id="@+id/logo_inner_iv"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher_inner"
        tools:alpha="1"/>

    <TextView
        android:id="@+id/app_name_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="80dp"
        android:alpha="0"
        android:text="Hi,Android"
        android:textColor="@color/white"
        android:textSize="18sp"
        tools:alpha="1"/>
</FrameLayout>

 5.xml动画:(Android动画之Interpolator(插值器)可以替换成:@android:anim/bounce_interpolator,其变化在结束时反弹)

anim_top_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:duration="1000"
     android:interpolator="@android:anim/accelerate_interpolator">

    <translate
        android:fromYDelta="-50%p"
        android:toYDelta="0%"/>
    <scale
        android:fromXScale="0.0"
        android:fromYScale="0.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.0"
        android:toYScale="1.0"/>
    <alpha
        android:fromAlpha="0.5"
        android:toAlpha="1"/>

</set>

fade_out.xml是Android API 28自带的 :

<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/res/anim/fade_out.xml
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/
-->

<alpha xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@interpolator/accelerate_quad" 
    android:fromAlpha="1.0"
    android:toAlpha="0.0"
    android:duration="@android:integer/config_mediumAnimTime" 
/>

 

 二.效果2:由小到大缩放动画效果

1.效果图:

android引导 android引导页动画_xml_02

 2.主函数代码:

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.daimajia.androidanimations.library.Techniques;
import com.daimajia.androidanimations.library.YoYo;
import com.hjq.demo.R;
import com.hjq.demo.ui.activity.sgf.search.SearchviewActivity;
import com.hjq.demo.utils.KickBackAnimator;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

/**
 * app启动动画系列
 * https://github.com/HMonkey1024/MyLauncher
 * https://github.com/darryrzhong/OpenEyes
 */
public final class SgfSplash6Activity extends AppCompatActivity {
    @BindView(R.id.lin)
    LinearLayout lin;
    @BindView(R.id.tv_sbs)
    TextView tv_sbs;
    @BindView(R.id.tv_search)
    TextView tv_search;
    @BindView(R.id.tv_course)
    TextView tv_course;
    @BindView(R.id.tv_task)
    TextView tv_task;
    private Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //全屏
//        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_sgf_splash6);
        ButterKnife.bind(this);

        ArrayList<TextView> textViews = new ArrayList<>();
        textViews.add(tv_sbs);
        textViews.add(tv_search);
        textViews.add(tv_course);
        textViews.add(tv_task);
//        showAnimation(textViews);
        showAnimation();
    }

    private void showAnimation() {
        tv_sbs.setVisibility(View.INVISIBLE);
        tv_search.setVisibility(View.INVISIBLE);
        tv_course.setVisibility(View.INVISIBLE);
        tv_task.setVisibility(View.INVISIBLE);
        Animation animation = AnimationUtils.loadAnimation(SgfSplash6Activity.this, R.anim.my_anim_scale2);
        tv_sbs.startAnimation(animation);
        tv_sbs.setVisibility(View.VISIBLE);
        mHandler.postDelayed(new Runnable() {

            @Override
            public void run() {

                //动画效果
                Animation animation = AnimationUtils.loadAnimation(SgfSplash6Activity.this, R.anim.my_anim_scale2);
                tv_search.startAnimation(animation);
                tv_search.setVisibility(View.VISIBLE);
                mHandler.postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        //动画效果
                        Animation animation = AnimationUtils.loadAnimation(SgfSplash6Activity.this, R.anim.my_anim_scale2);
                        tv_course.startAnimation(animation);
                        tv_course.setVisibility(View.VISIBLE);
                        mHandler.postDelayed(new Runnable() {

                            @Override
                            public void run() {
                                //动画效果
                                Animation animation = AnimationUtils.loadAnimation(SgfSplash6Activity.this, R.anim.my_anim_scale2);
                                tv_task.startAnimation(animation);
                                tv_task.setVisibility(View.VISIBLE);

                            }
                        }, 500);
                    }
                }, 500);
            }
        }, 500);
    }

    private void showAnimation(ArrayList<TextView> textViews) {
        try {
            //菜单项弹出动画
            for (int i = 0; i < textViews.size(); i++) {
//                textViews.get(i).setOnClickListener(this);
                textViews.get(i).setVisibility(View.INVISIBLE);
                int finalI = i;
                mHandler.postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        textViews.get(finalI).setVisibility(View.VISIBLE);

                        //动画效果1
//                        ValueAnimator fadeAnim = ObjectAnimator.ofFloat(textViews.get(finalI), "translationY", 600, 0);
//                        fadeAnim.setDuration(2000);
//                        KickBackAnimator kickAnimator = new KickBackAnimator();
//                        kickAnimator.setDuration(1500);
//                        fadeAnim.setEvaluator(kickAnimator);
//                        fadeAnim.start();

                        //动画效果2
//                        Animation animation = AnimationUtils.loadAnimation(SgfSplash6Activity.this, R.anim.anim_top_in);
//                        textViews.get(finalI).startAnimation(animation);

                        //动画效果3
//                        Animation animation = AnimationUtils.loadAnimation(SgfSplash6Activity.this, R.anim.my_anim_scale);
                        Animation animation = AnimationUtils.loadAnimation(SgfSplash6Activity.this, R.anim.my_anim_scale2);
                        textViews.get(finalI).startAnimation(animation);

                    }
                }, i * 50 + 1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

3.布局代码:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/wallpaper_12"
    tools:context=".ui.activity.sgf.guide.SgfSplash6Activity">

    <ImageView
        android:layout_gravity="center"
        android:src="@drawable/ic_share_wechat"
        android:layout_width="100dp"
        android:layout_height="100dp" />
    <LinearLayout
        android:id="@+id/lin"
        android:layout_marginTop="20dp"
        android:layout_gravity="center"
        android:gravity="center"
        android:src="@drawable/ic_share_wechat"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:paddingLeft="30dp"
        android:paddingRight="30dp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_sbs"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:gravity="center_horizontal"
            android:layout_marginTop="20dp"
            android:text="齐"
            android:textColor="@color/white"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/tv_search"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:layout_marginLeft="10dp"
            android:clickable="true"
            android:gravity="center_horizontal"
            android:text="天"
            android:textColor="@color/white"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/tv_course"
            android:layout_marginLeft="10dp"
            android:layout_width="wrap_content"
            android:layout_marginTop="20dp"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:gravity="center_horizontal"
            android:text="大"
            android:textColor="@color/white"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/tv_task"
            android:layout_marginLeft="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:layout_marginTop="20dp"
            android:gravity="center_horizontal"
            android:text="盛"
            android:textColor="@color/white"
            android:textSize="18sp" />
    </LinearLayout>
</FrameLayout>

4.xml动画

a.my_anim_scale2.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <scale
        android:duration="1000"
        android:fillAfter="false"
        android:fromXScale="0.0"
        android:fromYScale="0.0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.0"
        android:toYScale="1.0" />

</set><!--
     尺寸伸缩动画效果 scale
       属性:interpolator 指定一个动画的插入器
        在我试验过程中,使用android.res.anim中的资源时候发现
        有三种动画插入器:
            accelerate_decelerate_interpolator  加速-减速 动画插入器
            accelerate_interpolator        加速-动画插入器
            decelerate_interpolator        减速- 动画插入器
        其他的属于特定的动画效果
      浮点型值:

            fromXScale 属性为动画起始时 X坐标上的伸缩尺寸
            toXScale   属性为动画结束时 X坐标上的伸缩尺寸

            fromYScale 属性为动画起始时Y坐标上的伸缩尺寸
            toYScale   属性为动画结束时Y坐标上的伸缩尺寸

            说明:
                 以上四种属性值

                    0.0表示收缩到没有
                    1.0表示正常无伸缩
                    值小于1.0表示收缩
                    值大于1.0表示放大

            pivotX     属性为动画相对于物件的X坐标的开始位置
            pivotY     属性为动画相对于物件的Y坐标的开始位置

            说明:
                    以上两个属性值 从0%-100%中取值
                    50%为物件的X或Y方向坐标上的中点位置

        长整型值:
            duration  属性为动画持续时间
            说明:   时间以毫秒为单位

        布尔型值:
            fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用<br>-->

b.my_anim_scale.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <scale
        android:duration="1000"
        android:fillAfter="false"
        android:fromXScale="0.0"
        android:fromYScale="0.0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.4"
        android:toYScale="1.4" />

</set><!--
     尺寸伸缩动画效果 scale
       属性:interpolator 指定一个动画的插入器
        在我试验过程中,使用android.res.anim中的资源时候发现
        有三种动画插入器:
            accelerate_decelerate_interpolator  加速-减速 动画插入器
            accelerate_interpolator        加速-动画插入器
            decelerate_interpolator        减速- 动画插入器
        其他的属于特定的动画效果
      浮点型值:

            fromXScale 属性为动画起始时 X坐标上的伸缩尺寸
            toXScale   属性为动画结束时 X坐标上的伸缩尺寸

            fromYScale 属性为动画起始时Y坐标上的伸缩尺寸
            toYScale   属性为动画结束时Y坐标上的伸缩尺寸

            说明:
                 以上四种属性值

                    0.0表示收缩到没有
                    1.0表示正常无伸缩
                    值小于1.0表示收缩
                    值大于1.0表示放大

            pivotX     属性为动画相对于物件的X坐标的开始位置
            pivotY     属性为动画相对于物件的Y坐标的开始位置

            说明:
                    以上两个属性值 从0%-100%中取值
                    50%为物件的X或Y方向坐标上的中点位置

        长整型值:
            duration  属性为动画持续时间
            说明:   时间以毫秒为单位

        布尔型值:
            fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用<br>-->

android引导 android引导页动画_xml_03

 

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //全屏
//        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_sgf_splash6);
        ButterKnife.bind(this);

        ArrayList<TextView> textViews = new ArrayList<>();
        textViews.add(tv_sbs);
        textViews.add(tv_search);
        textViews.add(tv_course);
        textViews.add(tv_task);
//        showAnimation(textViews);

        tv_sbs.setVisibility(View.INVISIBLE);
        tv_search.setVisibility(View.INVISIBLE);
        tv_course.setVisibility(View.INVISIBLE);
        tv_task.setVisibility(View.INVISIBLE);
        Animation animation = AnimationUtils.loadAnimation(SgfSplash6Activity.this, R.anim.my_anim_translate2);
        iv_icon.startAnimation(animation);
        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                showAnimation();//动画结束时执行
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });

    }

 my_anim_translate2.xml   从上到下掉落弹性动画效果

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/bounce_interpolator">

    <translate
        android:duration="1500"
        android:fromXDelta="0"
        android:fromYDelta="-500"
        android:toXDelta="0"
        android:toYDelta="0" />
    <!--
     translate 位置转移动画效果
        整型值:
            fromXDelta 属性为动画起始时 X坐标上的位置
            toXDelta   属性为动画结束时 X坐标上的位置
            fromYDelta 属性为动画起始时 Y坐标上的位置
            toYDelta   属性为动画结束时 Y坐标上的位置
            注意:
                     没有指定fromXType toXType fromYType toYType 时候,
                     默认是以自己为相对参照物
        长整型值:
            duration  属性为动画持续时间
            说明:   时间以毫秒为单位
-->

</set>

 my_anim_translate3.xml    旋转渐变缩放一起执行动画效果

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fillAfter="true">

    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"/>

    <scale
        android:fromXScale="1.0"
        android:toXScale="1.4"
        android:fromYScale="1.0"
        android:toYScale="1.4"
        android:pivotX="50%"
        android:pivotY="50%"/>

    <rotate
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"/>

</set>

5.看看依赖:

apply plugin: 'com.android.application'

android {
    compileSdkVersion rootProject.ext.compileVersion

    // 使用 JDK 1.8
    compileOptions {
        targetCompatibility JavaVersion.VERSION_1_8
        sourceCompatibility JavaVersion.VERSION_1_8
    }
    lintOptions {
        abortOnError false
    }

    defaultConfig {
        // 无痛修改包名:https://www.jianshu.com/p/17327e191d2e
        applicationId "com.hjq.demo"
        minSdkVersion 19
        targetSdkVersion rootProject.ext.targetVersion
        versionCode 10
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        // 仅保留中文语种的资源
        resConfig 'zh'

        // 仅保留 xxhdpi 图片资源(目前主流分辨率 1920 * 1080)
        resConfig 'xxhdpi'

        // 仅保留两种架构的 so 库
        ndk {
            // armeabi:已经淘汰(0%)
            // armeabi-v7a:曾经主流的架构平台(20%)
            // arm64-v8a:目前主流架构平台(80%)
            //"x86_64",
            abiFilters "armeabi-v7a", "arm64-v8a", "x86", "armeabi"
        }

        // 开启 Dex 分包
        multiDexEnabled true

        // 混淆配置
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-app.pro'

        javaCompileOptions {
            annotationProcessorOptions {
                // EventBus Apt 索引类生成位置
                arguments = [ eventBusIndex : applicationId + '.MyEventBusIndex' ]
            }
        }
    }

    // APK 签名的那些事:https://www.jianshu.com/p/a1f8e5896aa2
    signingConfigs {
        debug {
            storeFile file(StoreFile)
            storePassword StorePassword
            keyAlias KeyAlias
            keyPassword KeyPassword
        }
        release {
            storeFile file(StoreFile)
            storePassword StorePassword
            keyAlias KeyAlias
            keyPassword KeyPassword
        }
    }

    buildTypes {
        release {
            // 移除无用的资源文件
            shrinkResources true
            // ZipAlign 优化
            zipAlignEnabled true
            // 设置混淆
            minifyEnabled true
            // 正式环境签名
            signingConfig signingConfigs.release
            // 正式环境下的 BuglyId
            buildConfigField "String", "BUGLY_ID", "\"请自行替换 Bugly 上面的 AppID\""
        }

        debug {
            // 移除无用的资源文件
            shrinkResources false
            // ZipAlign 优化
            zipAlignEnabled false
            // 设置混淆
            minifyEnabled false
            // 开发环境签名
            signingConfig signingConfigs.debug
            // 开发环境下的 BuglyId
            buildConfigField "String", "BUGLY_ID", "\"请自行替换 Bugly 上面的 AppID\""
        }
    }

    // 默认渠道名
    flavorDimensions "default"
    // 友盟多渠道打包
    productFlavors {
        tencent {}  // 应用宝
        baidu {}    // 百度
        xiaomi {}   // 小米
        huawei {}   // 华为

        productFlavors.all { flavor ->
            flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
        }
    }

    // JNI 目录
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

    // 执行配置
    applicationVariants.all { variant ->

        // Apk 输出配置
        variant.outputs.all { output ->
            def appName = "AndroidProject"
            if (variant.buildType.name == 'debug') {
                outputFileName = appName + '_v' + versionName + '_' + variant.buildType.name + '.apk'
            } else {
                outputFileName = appName + '_v' + versionName + '_' + new Date().format("yyyyMMdd") + '_' + variant.productFlavors[0].name + '_' + variant.buildType.name + '.apk'
            }
        }

        // AndroidManifest 输出配置
        variant.outputs[0].processManifest.doLast {
            def manifestFile = "${manifestOutputDirectory}/AndroidManifest.xml"
            def updatedContent = new File(manifestFile).getText('UTF-8')
                    .replaceAll("UMENG_APPKEY_VALUE", "5cb16d93570df399fd0014e2") // 友盟 AppKey
                    .replaceAll("QQ_APPID_VALUE", "100424468") // QQ AppId
                    .replaceAll("QQ_APPKEY_VALUE", "c7394704798a158208a74ab60104f0ba") // QQ Key
                    .replaceAll("WX_APPID_VALUE", "wxdc1e388c3822c80b") // 微信 AppId
                    .replaceAll("WX_APPKEY_VALUE", "3baf1193c85774b3fd9d18447d76cab0") // 微信 Key
            new File(manifestFile).write(updatedContent, 'UTF-8')
        }
    }
}

// api 与 implementation 的区别:https://www.jianshu.com/p/8962d6ba936e
dependencies {
    // 依赖 libs 目录下所有 jar 包
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    // 依赖 libs 目录下所有 aar 包
    implementation fileTree(include: ['*.aar'], dir: 'libs')

    // 基础库(不包任何第三方框架)
    implementation project(':base')
    // 自定义 View
    implementation project(':widget')
    // Glide 隔离
    implementation project(':image')
    // 友盟隔离
    implementation project(':umeng')

    // 谷歌 Support 包
    implementation "androidx.appcompat:appcompat:$rootProject.ext.appcompatVersion"
    implementation "com.google.android.material:material:$rootProject.ext.materialVersion"

    // Dex 分包,解决 64k 方法问题
    implementation 'androidx.multidex:multidex:2.0.1'

    // ButterKnife 注解库:https://github.com/JakeWharton/butterknife
    implementation 'com.jakewharton:butterknife:10.1.0'
    annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'

    // EventBus 事件总线:https://github.com/greenrobot/EventBus
    implementation "org.greenrobot:eventbus:3.1.1"
    annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1'

    // 状态栏沉浸:https://github.com/gyf-dev/ImmersionBar
    implementation 'com.gyf.immersionbar:immersionbar:3.0.0'

    // 权限请求框架:https://github.com/getActivity/XXPermissions
    implementation 'com.hjq:xxpermissions:6.0'

    // 标题栏:https://github.com/getActivity/TitleBar
    implementation 'com.hjq:titlebar:6.0'

    // 吐司工具类:https://github.com/getActivity/ToastUtils
    implementation 'com.hjq:toast:8.0'

    // 支持放大缩放的 ImageView:https://github.com/chrisbanes/PhotoView
    implementation 'com.github.chrisbanes:PhotoView:2.3.0'
    // ViewPager 指示器:https://github.com/romandanylyk/PageIndicatorView
    implementation 'com.romandanylyk:pageindicatorview:1.0.3'

    // Bugly 异常捕捉:https://bugly.qq.com/docs/user-guide/instruction-manual-android/?v=20190418140644
    implementation 'com.tencent.bugly:crashreport:3.0.1'
    implementation 'com.tencent.bugly:nativecrashreport:3.7.1'

    // 本地异常捕捉框架:https://github.com/Ereza/CustomActivityOnCrash
    implementation 'cat.ereza:customactivityoncrash:2.2.0'

    // 内存泄漏捕捉:https://github.com/square/leakcanary
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.4'
    releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'

    // 网络请求(待发布):https://github.com/getActivity/EasyHttp

    // 国际化:https://github.com/getActivity/MultiLanguages
    // 悬浮窗:https://github.com/getActivity/XToast
    // 上拉刷新下拉加载:https://github.com/scwang90/SmartRefreshLayout
    // 工具类:https://github.com/Blankj/AndroidUtilCode
    // 轮播图:https://github.com/bingoogolapple/BGABanner-Android
    // 二维码:https://github.com/bingoogolapple/BGAQRCode-Android
    // 第三方支付:https://github.com/getActivity/RxPay
    // Log 打印:https://github.com/elvishew/XLog
    // 图片压缩:https://github.com/Curzibn/Luban
    // 对象存储:https://github.com/leavesC/DoKV
    // 数据注入:https://github.com/JumeiRdGroup/Parceler

    implementation 'com.android.support:design:26.1.0'
    //约束布局
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    //第三方适配器
    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'
    implementation 'com.google.code.gson:gson:2.8.0'
//    implementation 'com.github.bumptech.glide:glide:3.7.0'

    //通用标题栏
    implementation 'com.hjq:titlebar:6.0'
    implementation 'com.makeramen:roundedimageview:2.3.0'
    //高度自定义的开源安卓视频框架
    implementation 'cn.jzvd:jiaozivideoplayer:7.0.5'
    implementation 'com.danikula:videocache:2.7.0'
//    implementation 'com.github.bumptech.glide:glide:4.7.1'
    implementation 'com.github.bumptech.glide:glide:4.9.0'
    //
    annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
    dependencies {
        implementation ('com.google.android.exoplayer:exoplayer:2.9.1'){

        }
    }
//    dependencies {
//        implementation ('com.github.bumptech.glide:glide:4.7.1'){
//
//        }
//    }
    implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
    implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4'
//    implementation 'com.google.android.exoplayer:exoplayer:2.9.1'
    //圆形图片
    implementation 'de.hdodenhof:circleimageview:2.2.0'
    //弹簧动画效果
    implementation 'com.facebook.rebound:rebound:0.3.8'
    //抖音APP点赞效果实现,模仿抖音APP双击屏幕蹦出心图,特点: 1. 可以自定义图片 2. 可以自定义旋转角度 3. 超级简洁,占用内存小
    implementation 'com.github.KevinYou128:HotHeart:v1.2'

    //轮播图  https://github.com/bingoogolapple/BGABanner-Android
    implementation 'com.android.support:support-v4:latestVersion'
    implementation 'cn.bingoogolapple:bga-banner:2.2.7@aar'
    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'cn.bingoogolapple:bga-baseadapter:1.2.9@aar'

    implementation 'com.facebook.fresco:fresco:1.5.0'
//    implementation 'com.android.support:multidex:1.+'
    //轮播图  https://github.com/bingoogolapple/BGABanner-Android

    //一个富有动感的Sheet(选择器)
    implementation 'com.github.zzz40500:AndroidSweetSheet:1.1.0'

    //实现九宫格框架
//   implementation 'com.wobiancao:imagenice9lib:1.0.1'
//    implementation('com.wobiancao:imagenice9lib:1.0.1') {
//        transitive = true;
//    }
    //阿里巴巴推出的一个RecyclerView得扩展库vlayout
    implementation ('com.alibaba.android:vlayout:1.2.8@aar') {
        transitive = true
    }
    //3D 外科调试工具,可发现您应用下的图层
    implementation 'com.jakewharton.scalpel:scalpel:1.1.2'
    //RecyclerView扩展库提供了高级功能。 (例如,Google的Inbox应用(例如滑动,Play Music应用(例如,拖放排序)
    implementation 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:1.0.0'
    //
    implementation 'com.alibaba:fastjson:1.2.56'

    implementation 'com.flyco.tablayout:FlycoTabLayout_Lib:2.0.0@aar'
    implementation 'com.trello:rxlifecycle-components:0.6.1'
    implementation 'com.zhy:flowlayout-lib:1.0.1'

    //动画
    implementation 'com.daimajia.androidanimations:library:1.1.3@aar'
}