Android中几乎所有app都有启动页这一基本功能,但是用途都不相同。 有的app的启动页用于加载广告,有的启动页用于加载后台,一旦后台数据加载好了才把启动页去了,不过想来很多app是两者兼顾的。 需求:
展示 logo 页面3秒 服务端可以控制是否播放广告 服务端可以控制播放广告的秒数 服务端可以控制广告的内容(图片)和广告详情页面的链接
注意:从服务端请求数据是在展示 3 秒启动页的时候获取的
启动页 启动包括冷启动和热启动:
冷启动:是指进程从无到有的过程。因为要进行页面初始化,所以相对其他两个启动方式,消耗的时间是相对比较多的。 热启动:是指之前的进程还在,在之前进程的基础上创建 Activity 的过程,耗时相对少一点。 我们可以通过 Activity 的 theme 来修改这个白屏所显示的界面。根据上面的需求,我们需要显示3秒 logo 的页面。那么我们干脆将我们的logo设置为背景图就行了。 新建一个activity为SplashActivity,其对应布局文件为activity_splash.xml 并在AndroidManifest.xml中将SplashActivity设置为主入口:
1 2 3 4 5 6 7 8 9 <activity android:name =".MainActivity" > </activity > <activity android:name =".SplashActivity" android:theme ="@style/Theme.AppCompat.NoActionBar.NoActionBarWithBackGround" > <intent-filter > <action android:name ="android.intent.action.MAIN" /> <category android:name ="android.intent.category.LAUNCHER" /> </intent-filter > </activity >
在values中的themes.xml中添加:
1 2 3 4 5 6 <style name ="Theme.AppCompat.NoActionBar.NoActionBarWithBackGround" > <item name ="windowActionBar" > false</item > //取消Actionbar <item name ="windowNoTitle" > true</item > <item name ="android:windowFullscreen" > true</item > //设置全屏 <item name ="android:windowBackground" > @drawable/splash</item > //设置背景图片 </style >
在AndroidManifest.xml中需要主题的Activity添加:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?xml version="1.0" encoding="utf-8" ?> <manifest xmlns:android ="http://schemas.android.com/apk/res/android" package ="com.example.splashactivity" > <application android:allowBackup ="true" android:icon ="@mipmap/ic_launcher" android:label ="@string/app_name" android:roundIcon ="@mipmap/ic_launcher_round" android:supportsRtl ="true" android:theme ="@style/Theme.SplashActivity" > <activity android:name =".MainActivity" > </activity > <activity android:name =".SplashActivity" android:theme ="@style/Theme.AppCompat.NoActionBar.NoActionBarWithBackGround" > <intent-filter > <action android:name ="android.intent.action.MAIN" /> <category android:name ="android.intent.category.LAUNCHER" /> </intent-filter > </activity > </application > </manifest >
SplashActivity:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.WindowManager;public class SplashActivity extends Activity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_splash); Thread myThread = new Thread () { @Override public void run () { try { sleep(5000 ); Intent intent = new Intent (getApplicationContext(), MainActivity.class); startActivity(intent); finish(); } catch (Exception e) { e.printStackTrace(); } } }; myThread.start(); } }
广告页 广告页我尝试过两种方式: 1.glide 加载 2.通过下载文件,然后再加载 如果使用glide加载广告图片,如果网络比较差,会存在广告页面空白的情况,因为使用 glide 无法判断在 3 秒展示 logo 的页面是否加载好了广告图片。这给用户的体验是比较差的,也是不太友好的,因为用户在空白界面拜拜等待了 3 秒。所以后面使用了将广告图片下载到本地的方法。
动画开屏 新建EmptyActivity–AnimatedActivity 在build.gradle(:app)的dependencies中添加glide依赖:
implementation ‘com.github.bumptech.glide:glide:4.12.0’ 然后点击sync now
新建动画所需的VectorAsset:
然后点击next,最后点击finish转换svg的网站
或者去iconfont 查找
activity_animated 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 <?xml version="1.0" encoding="utf-8" ?> <RelativeLayout 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" tools:context =".AnimatedActivity" > <ImageView android:layout_width ="match_parent" android:layout_height ="wrap_content" android:id ="@+id/iv_top" android:adjustViewBounds ="true" android:src ="@drawable/ic_top_vector" /> <LinearLayout android:layout_width ="match_parent" android:layout_height ="match_parent" android:orientation ="vertical" android:gravity ="center" android:padding ="16dp" > <ImageView android:layout_width ="match_parent" android:layout_height ="180dp" android:id ="@+id/iv_heart" android:adjustViewBounds ="true" android:src ="@drawable/ic_heart" /> <TextView android:layout_width ="wrap_content" android:layout_height ="wrap_content" android:id ="@+id/text_view" android:textSize ="48sp" android:textStyle ="bold" android:textColor ="#D75A4A" android:layout_marginTop ="8dp" /> <ImageView android:layout_width ="match_parent" android:layout_height ="wrap_content" android:id ="@+id/iv_beat" android:adjustViewBounds ="true" /> </LinearLayout > <ImageView android:layout_width ="match_parent" android:layout_height ="wrap_content" android:id ="@+id/iv_bottom" android:adjustViewBounds ="true" android:layout_alignParentBottom ="true" android:src ="@drawable/ic_bottom_vector" /> </RelativeLayout >
新建ResourceFile
设置:
top_wave.xml 1 2 3 4 5 6 7 8 9 10 11 12 <?xml version="1.0" encoding="utf-8" ?> <set xmlns:android ="http://schemas.android.com/apk/res/android" > <translate android:fromXDelta ="-50%" android:fromYDelta ="0%" android:duration ="2500" /> <alpha android:fromAlpha ="1.0" android:toAlpha ="0.5" android:duration ="2500" /> </set >
bottom_wave.xml 1 2 3 4 5 6 7 8 9 10 11 <?xml version="1.0" encoding="utf-8" ?> <set xmlns:android ="http://schemas.android.com/apk/res/android" > <translate android:duration ="2500" android:fromXDelta ="50%" android:fromYDelta ="0%" /> <alpha android:duration ="2500" android:fromAlpha ="1.0" android:toAlpha ="0.5" /> </set >
AnimatedActivity 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 import android.animation.ObjectAnimator;import android.animation.PropertyValuesHolder;import android.animation.ValueAnimator;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import android.view.WindowManager;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import android.widget.ImageView;import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;import com.bumptech.glide.Glide;import com.bumptech.glide.load.engine.DiskCacheStrategy;public class AnimatedActivity extends AppCompatActivity { ImageView ivTop, ivHeart, ivBeat, ivBottom; TextView textView; CharSequence charSequence; int index; long delay = 200 ; Handler mHandler = new Handler (); @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_animated); ivTop = findViewById(R.id.iv_top); ivHeart = findViewById(R.id.iv_heart); ivBottom = findViewById(R.id.iv_bottom); textView = findViewById(R.id.text_view); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN , WindowManager.LayoutParams.FLAG_FULLSCREEN); Animation animation1 = AnimationUtils.loadAnimation(this , R.anim.top_wave); ivTop.setAnimation(animation1); ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder( ivHeart, PropertyValuesHolder.ofFloat("scaleX" , 1.2f ), PropertyValuesHolder.ofFloat("scaleY" , 1.2f ) ); objectAnimator.setDuration(500 ); objectAnimator.setRepeatCount(ValueAnimator.INFINITE); objectAnimator.setRepeatMode(ValueAnimator.REVERSE); objectAnimator.start(); animateText("Heart Beat" ); Glide.with(this ).load("https://firebasestorage.googleapis.com/v0/b/demoapp-ae96a.appspot.com/o/heart_beat.gif?alt=media&token=b21dddd8-782c-457c-babd-f2e922ba172b" ) .diskCacheStrategy(DiskCacheStrategy.ALL) .into(ivBottom); Animation animation2 = AnimationUtils.loadAnimation(this , R.anim.bottom_wave); ivBottom.setAnimation(animation2); new Handler ().postDelayed(new Runnable () { @Override public void run () { startActivity(new Intent (AnimatedActivity.this , MainActivity.class) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); finish(); } }, 4000 ); } Runnable mRunnable = new Runnable () { @Override public void run () { textView.setText(charSequence.subSequence(0 , index++)); if (index <= charSequence.length()) { mHandler.postDelayed(mRunnable, delay); } } }; public void animateText (CharSequence cs) { charSequence = cs; index = 0 ; textView.setText("" ); mHandler.removeCallbacks(mRunnable); mHandler.postDelayed(mRunnable, delay); } }
在AndroidManifest.xml中添加权限:
1 <uses-permission android:name ="android.permission.INTERNET" />
不要忘记将AnimatedActivity设置为主入口.
完整项目