Saturday, July 23, 2022

Splash screen on Android 12

 Setup splash screen on Android 12


Trong bài viết trước, chúng tôi có đề cập tới sự thay đổi về "màn hình chào" - Splash screen trong Android 12. Và trong bài viết này, chúng tôi sẽ hướng dẫn các bạn thiết lập điều đó.

Eng Sub: 


Step 1: Open your project or create if it is new project

Step 2: Editing in Gradle files

android {
compileSdk 31

defaultConfig {
applicationId "com.tnv.splashscreenandroid12"
minSdk 26
targetSdk 31
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
}

dependencies {

implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

// splash screen library
implementation 'androidx.core:core-splashscreen:1.0.0-beta02'
}


Code ở trên là file Gradle của tôi, còn của bạn chỉ cần chú ý đoạn code sau: 

android {
compileSdk 32

defaultConfig {
applicationId "com.tnv.splashscreenandroid12"
minSdk 26
targetSdk 32
...
}

...
}


Và chú ý thêm một đoạn code thêm Dependency (thư viện của Splash screen Android 12)

// splash screen library
implementation 'androidx.core:core-splashscreen:1.0.0-beta02'


Để chắc chắn rằng project của bạn đã apply cho Android level 12 và đã có đầy đủ thư viện.

Step 3: Create an animation for the movement of the logo:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false" >
<item android:drawable="@drawable/icon1" android:duration="500"/>
<item android:drawable="@drawable/icon2" android:duration="500"/>
<item android:drawable="@drawable/icon3" android:duration="500"/>

</animation-list>


Bạn có thể tạo những animation theo ý muốn về các chuyển động của logo sao cho ứng dụng của bạn đẹp mắt hơn.

Danh sách các hình ảnh dùng cho animation trên:

Eng Sub: 



Step 4: Create a parent style for the application (main style)

<style name="Theme.SplashScreenAndroid12" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
</style>


Step 5: Create a style in xml for the Splash screen

<style name="Theme.App.Starting" parent="Theme.SplashScreen">
<!-- Set the splash screen background, animated icon, and animation duration. -->
<item name="windowSplashScreenBackground">#fff</item>

<!-- Use windowSplashScreenAnimatedIcon to add either a drawable or an
animated drawable. One of these is required. -->
<item name="windowSplashScreenAnimatedIcon">@drawable/animation_logo</item>
<!-- Required for animated icons -->
<item name="windowSplashScreenAnimationDuration">1000</item>

<!-- Set the theme of the Activity that directly follows your splash screen. -->
<!-- Required -->
<item name="postSplashScreenTheme">@style/Theme.SplashScreenAndroid12</item>
</style>


item name="windowSplashScreenBackground" Là màu nền của màn hình splash screen

item name="windowSplashScreenAnimatedIcon" Là icon hay logo mà bạn muốn show trong màn hình splash screen. Chổ này bạn có thể đặt vào icon của ứng dụng hoặc một hình ảnh nào đó do bạn thiết kế hoặc một vector hoặc một animation list cũng được. 

item name="windowSplashScreenAnimationDuration" Là thời gian animation của chính cái logo trên

item name="postSplashScreenTheme" Là thuộc tính chỉ định theme hiển thị cho splash screen.     


Eng Sub: 



Step 6: Set splash screen theme declaration in AndroidManifest.xml

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

<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.SplashScreenAndroid12">

<!--main screen-->
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.App.Starting">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<!--second screen-->
<activity
android:theme="@style/Theme.SplashScreenAndroid12"
android:name=".SecondActivity"
android:exported="false" />

</application>

</manifest>


Chú ý đoạn code sau ở dòng android:theme="@style/Theme.App.Starting"> trong "main screen"    

<!--main screen-->
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.App.Starting">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>


Step 7: Call installSplashScreen in startup activity before calling super.onCreate()

public class MainActivity extends AppCompatActivity {

@RequiresApi(api = Build.VERSION_CODES.S)
@Override
protected void onCreate(Bundle savedInstanceState) {
// initial splash screen
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}


Step 8: Run the app to experience

Ở bước này, chúng tối muốn trải nghiệm sự khác biệt khi build và chạy ứng dụng của Android 12 so với các level Android từ 11 trở về trước.

Eng Sub: 



Step 9: Create second Activity

Code java:

public class SecondActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}


Code layout xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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:orientation="vertical"
android:gravity="center"
tools:context=".SecondActivity">

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Home Screen"
android:textStyle="bold"
android:textColor="#000"
android:textSize="25sp"
tools:layout_editor_absoluteX="183dp"
tools:layout_editor_absoluteY="350dp"
tools:ignore="MissingConstraints" />

</LinearLayout>


Eng Sub: 



Step 10: Next, customize the animations and move on to the second screen:

Trong class MainActivity.java bạn code lại như sau: 

public class MainActivity extends AppCompatActivity {

@RequiresApi(api = Build.VERSION_CODES.S)
@Override
protected void onCreate(Bundle savedInstanceState) {
// initial splash screen
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);

splashScreen.setKeepOnScreenCondition(() -> false );

getSplashScreen().setOnExitAnimationListener(new android.window.SplashScreen.OnExitAnimationListener() {
@Override
public void onSplashScreenExit(@NonNull SplashScreenView splashScreenView) {
final ObjectAnimator slideUp = ObjectAnimator.ofFloat(
splashScreenView,
View.TRANSLATION_Y,
0f,
splashScreenView.getHeight()
);
slideUp.setInterpolator(new AnticipateInterpolator());
slideUp.setDuration(3000);

// Call SplashScreenView.remove at the end of your custom animation.
slideUp.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
splashScreenView.remove();

// start second screen here
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
startSomeNextActivity();
}
}, 2000);
}
});

// Run your animation.
slideUp.start();
}
});

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

private void startSomeNextActivity() {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);

finish();
}
}


Bạn chú ý dòng code này splashScreen.setKeepOnScreenCondition(() -> false ); nó cho phép Splash screen hoạt động có Animation hay không.

Nếu bạn set giá trị cho nó là false thì bạn có thể tùy biến việc animation cho màn hình splash screen biến mất. Bên cạnh đó, Android 12 cũng cung cấp cho bạn một listener để bắt sự kiện đó, từ đó có thể chuyển màn hình kế tiếp hoặc đặt các xử lý tiếp theo sự mong muốn của bạn. 

Nếu bạn set giá trị cho nó là true thì điều này có nghĩa là bạn muốn giữ màn hình splash screen hiển thị một thời gian nào đó rồi mới thực hiện bước xử lý tiếp theo. Trường hợp này là bạn không muốn có animation, chủ yếu để quản cáo thương hiệu hoặc cung cấp thông tin lâu hơn cho người dùng .v..v...

Trường hợp cho True: 

public class MainActivity extends AppCompatActivity {

@RequiresApi(api = Build.VERSION_CODES.S)
@Override
protected void onCreate(Bundle savedInstanceState) {
// initial splash screen
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);

splashScreen.setKeepOnScreenCondition(() -> true );

new Handler().postDelayed(new Runnable() {
@Override
public void run() {
startSomeNextActivity();
}
}, 2000);

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

private void startSomeNextActivity() {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);

finish();
}
}


Trường hợp cho False:

public class MainActivity extends AppCompatActivity {

@RequiresApi(api = Build.VERSION_CODES.S)
@Override
protected void onCreate(Bundle savedInstanceState) {
// initial splash screen
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);

splashScreen.setKeepOnScreenCondition(() -> false );

getSplashScreen().setOnExitAnimationListener(new android.window.SplashScreen.OnExitAnimationListener() {
@Override
public void onSplashScreenExit(@NonNull SplashScreenView splashScreenView) {
final ObjectAnimator slideUp = ObjectAnimator.ofFloat(
splashScreenView,
View.TRANSLATION_Y,
0f,
splashScreenView.getHeight()
);
slideUp.setInterpolator(new AnticipateInterpolator());
slideUp.setDuration(3000);

// Call SplashScreenView.remove at the end of your custom animation.
slideUp.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
splashScreenView.remove();

// start second screen here
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
startSomeNextActivity();
}
}, 2000);
}
});

// Run your animation.
slideUp.start();
}
});
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

private void startSomeNextActivity() {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);

finish();
}
}


Bạn chạy thử 2 trường hợp trên để trải nghiệm nhé.

Sự thú vị nhất của lần cập nhật này là chúng ta có nhiều tùy biến cho màn chình chào mà không cần phải tạo nhiều màn hình trong ứng dụng như trước. Màn hình chào cũng chính là màn hình "Home" trong ứng dụng. Ở bài viết này, chúng tôi còn áp dụng các cách code và luồng suy nghĩ cũ. Ở bài viết nâng cao với Splash screen, chúng tôi sẽ dùng chỉ một màn hình "Home" cho tất cả.

Eng Sub: