Android SplashActivity

App啓動頁

打開一個應用程序時,第一眼看到的並不是主程序的界面,而是一個類似歡迎的界面,它叫SplashActivity一般在這個頁面可以做一些App數據初始化的工作。(splash,潑灑,渲染)

SplashActivity的實現

實現的效果當用戶點擊App icon後,進入SplashActivity,大約經過1~2秒跳轉到程序的主界面

SplashActivity的全屏效果

一般App的啓動頁都是全屏。可以用於顯示一些App logo,或者加載一些廣告,圖片...一般實現全屏效果有以下幾種方式:

  • 在代碼中給window設置flag
  • 給Application或者Activity設置主題

Window.setFlags

supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

注意:在setContentView()之前調用

style

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>

</style>

<style name="AppTheme.NoTitle">
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
</style>

<style name="AppTheme.NoTitle.FullScreen">
    <item name="android:windowFullscreen">true</item>
</style>

在AndroidManifests.xml中給activity或者application的android:theme屬性設置

選用哪一個windowNoTitle/windowActionBar屬性

在編寫SplashActivity時,選擇繼承自兼容包的AppCompatActivity。所以主題屬性應該選擇Theme.AppCompat Theme,否則運行時會中斷。log如下:

Theme error log.png

而在Theme.AppCompat主題包含的屬性中有兩個屬性windowNoTitlewindowActionBar用來決定是否顯示默認的ActionBar。打開Theme.AppCompat.NoActionBar style後發現,就是修改了上述兩個屬性實現NoActionBar。

Theme.AppCompat.NoActionBar:

<style name="Theme.AppCompat.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

windowNoTitlewindowActionBar分別有兩個類似的屬性:android:windowNoTitleandroid:windowNoActionBar這是Android系統包Activity的Theme的屬性。所以改變這兩個值是沒有用的。

SplashActivity設置爲啓動頁

在AndroidManifests.xml中爲SplashActivity設置啓動的屬性

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="android.example.com.zhihudaily">

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".activity.SplashActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
    <activity android:name=".MainActivity"
        android:theme="@style/AppTheme.NoTitle"/>
</application>

</manifest>

實現跳轉

在指定的時間內跳轉到程序的主界面有很多種方式,這裏採用動畫效果的方式。當動畫結束時,自動跳轉到指定的activity。

protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_splash);
    initView();
}

private void initView() {
    mImgStart = (ImageView) findViewById(R.id.id_img_start);
    iniImage();
}

private void iniImage() {
    File dir = getFilesDir();
    File imageFile = new File(dir, "start.jpg");
    if(imageFile.exists()) {
        mImgStart.setImageBitmap(BitmapFactory.decodeFile(imageFile.getAbsolutePath()));
    }else {
        mImgStart.setImageResource(R.mipmap.start);
    }

    ScaleAnimation scaleAnim = new ScaleAnimation(
            1.0f,
            1.2f,
            1.0f,
            1.2f,
            Animation.RELATIVE_TO_SELF,
            0.5f,
            Animation.RELATIVE_TO_SELF,
            0.5f
    );

    scaleAnim.setFillAfter(true);
    scaleAnim.setDuration(3000);
    scaleAnim.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            //在這裏做一些初始化的操作
            //跳轉到指定的Activity
            startActivity();
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    });
    mImgStart.startAnimation(scaleAnim);
}

private void startActivity() {
    Intent intent = new Intent(SplashActivity.this, MainActivity.class);
    startActivity(intent);
    overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
    finish();
}   

跳轉效果問題

由於給SplashActivity實現了全屏的效果,而跳轉到的Activity並非全屏時,會出現一個"卡頓"StatusBar從隱藏狀態變成顯示狀態,導致Toolbar整體下移。如下圖:

Toolbar下移.gif

同時發現Android5.0以後StatusBar默認狀態時半透明狀態。所以就想通過改變狀態欄的顏色的同時,解決這個生硬的效果。

protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    translucentStatusBar();
}

private void translucentStatusBar() {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
        ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
        int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        decorView.setSystemUiVisibility(option);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
    }
}

這裏先適配了5.0以上的系統

並且給ToolBar設置minHeight屬性,這樣看上去和ActionBar高度一樣

private void initView() {
    mToolbar = (Toolbar) findViewById(R.id.id_toolbar);
    int statusBarHeightId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    int statusBarHeight = getResources().getDimensionPixelSize(statusBarHeightId);
    TypedArray ta = obtainStyledAttributes(new int[]{android.R.attr.actionBarSize});
    int actionBarSize = ta.getDimensionPixelSize(0, 0);
    mToolbar.setMinimumHeight(actionBarSize + statusBarHeight);
}

最終效果:

SplahActivity.gif

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章