افزودن صفحه آغازین (Splash Screen) به اپ React Native — از صفر تا صد

۱۸۳ بازدید
آخرین به‌روزرسانی: ۲۰ شهریور ۱۴۰۲
زمان مطالعه: ۹ دقیقه
افزودن صفحه آغازین (Splash Screen) به اپ React Native — از صفر تا صد

مراحل نهایی‌سازی یک اپلیکیشن و ارائه آن در اپ‌استورهای مختلف به مراتب پیچیده‌تر از توسعه خود آن است و شامل کارهایی مانند افزودن آیکون‌ها، «صفحه‌های آغازین» (Splash Screens)، نوشتن توضیح و موارد دیگر می‌شود. در این مقاله به بررسی روش افزودن صفحه آغازین به اپ‌های ری‌اکت نیتیو برای پلتفرم‌های iOS و Android می‌پردازیم.

بدین منظور روی IDE-های متناظر هر پلتفرم کار می‌کنیم و مقداری کد نیتیو می‌نویسیم. به هیچ وجه جای نگرانی وجود ندارد، زیرا توضیحات کاملاً جامع هستند. برای مشاهده کد نهایی می‌توانید به این ریپوی گیت‌هاب (+) مراجعه کنید.

در ابتدا یک اپلیکیشن React Native جدید با دستور زیر می‌سازیم:

react-native init SplashExample

نکته: پیش از ادامه مطالعه این مقاله، کنترل سورس را راه‌اندازی کنید. این نه‌تنها یک روش مناسب برای بازگردانی تغییرات در صورت بروز اشتباه است، بلکه یک روش مناسب برای بررسی این نکته است که چه چیزی دقیقاً عوض شده است تا صفحه آغازین فعال شود.

فایل‌های صفحه آغازین

ما در راهنما می‌توانستیم از یک تصویر بزرگ برای صفحه آغازین استفاده کنیم، اما این امر موجب استفاده از مقیاس‌بندی بین وضوح‌های مختلف صفحه‌های گوشی می‌شد که مداوماً نیز در حال رشد هستند. بنابراین به جای آن، کار خود را با یک تصویر منفرد آغاز می‌کنیم که بیشتر شبیه به آیکون به نظر می‌رسد. این ایده دو جنبه دارد:

وقتی تصویر شبیه آیکون است کاربر تشویق می‌شود که روی آن ضربه بزند و با این کار تصویر به اندازه صفحه بزرگ می‌شود و این کار در طی یک گذار بی توقف صورت می‌گیرد.

همه چیز ساده می‌ماند. یک صفحه آغازین صرفاً برای چند میلی‌ثانیه نمایش می‌یابد و نباید اطلاعات زیادی روی آن قرار داشته باشند چون در هر صورت یک صفحه بارگذاری محسوب می‌شود.

با داشتن این ذهنیت کار خود را با یک تصویر مربعی در سه اندازه زیر شروع می‌کنیم:

  • @1x = 200px
  • @2x = 400px
  • @3x = 600px

این تصاویر را می‌توانید از اینجا (+) دانلود کنید.

صفحه آغازین

آماده‌سازی اپلیکیشن

اگر تاکنون تلاش کرده باشید یک صفحه آغازین در React Native تنظیم کنید، ممکن است یک صفحه سفید را که پیش از بارگذاری محتوا چشمک می‌زند، تجربه کرده باشید. اگر اپلیکیشن شما دارای پس‌زمینه سفید باشد، این مسئله معمولاً چندان به چشم نمی‌آید، اما در هر صورت یک مشکل محسوب می‌شود.

در این راهنما قصد داریم کاری کنیم که اگر چنین چیزی وجود دارد، کاملاً به چشم بیاید. به این منظور یک رنگ پس‌زمینه تیره برای اپلیکیشن خود انتخاب می‌کنیم. به این منظور محتوای App.js را با کد زیر عوض کنید:

1import React, { Component } from 'react';
2import {
3  Platform,
4  StyleSheet,
5  Text,
6  View,
7  StatusBar
8} from 'react-native';
9
10const instructions = Platform.select({
11  ios: 'Press Cmd+R to reload,\n' +
12    'Cmd+D or shake for dev menu',
13  android: 'Double tap R on your keyboard to reload,\n' +
14    'Shake or press menu button for dev menu',
15});
16
17export default class App extends Component {
18  render() {
19    return (
20      <View style={styles.container}>
21        <StatusBar
22          barStyle="light-content"
23          backgroundColor="#4F6D7A"
24        />
25        <Text style={styles.welcome}>
26          Welcome to React Native!
27        </Text>
28        <Text style={styles.instructions}>
29          To get started, edit App.js
30        </Text>
31        <Text style={styles.instructions}>
32          {instructions}
33        </Text>
34      </View>
35    );
36  }
37}
38
39const styles = StyleSheet.create({
40  container: {
41    flex: 1,
42    justifyContent: 'center',
43    alignItems: 'center',
44    backgroundColor: '#4F6D7A',
45  },
46  welcome: {
47    fontSize: 20,
48    textAlign: 'center',
49    margin: 10,
50    color: '#F5FCFF',
51  },
52  instructions: {
53    textAlign: 'center',
54    color: '#F5FCFF',
55    marginBottom: 5,
56  },
57});

همه این کارها موجب شد که رنگ پس‌زمینه به #4F6D7A و رنگ متن به #F5FCFF عوض شود و از متن روشن در نوار وضعیت استفاده شود.

صفحه آغازین

افزودن صفحه آغازین به iOS

ابتدا پروژه را در Xcode باز کنید.

1open ios/SplashExample.xcodeproj

سپس یک فایل تصویر جدید درون Xcode اضافه کنید. در ناوبری سمت چپ می‌توانید به این فایل دسترسی پیدا کنید (SplashExample > SplashExample > Imagex.xcassets) و سپس کلید + را در ناوبری دوم سمت چپ کلیک کنید. نام آن را SplashIcon بگذارید.

صفحه آغازین
برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

سپس ادامه می‌دهیم و سه تصویر که قبلاً دانلود کردیم را به پروژه اضافه می‌کنیم. این تصاویر به صورت خودکار خودشان را به تراکم پیکسلی صحیح الحاق می‌کنند.

صفحه آغازین
برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

سپس می‌توانید LaunchScreen.xib را که در ناوبری سمت چپ موجود است را باز کنید. بدین ترتیب با تصویر زیر مواجه می‌شوید.

صفحه آغازین
برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

دو عنصر متنی را انتخاب و آن‌ها را حذف کنید.

سپس رنگ پس‌زمینه View را تنظیم می‌کنیم. به این منظور View را در ناوبری دوم سمت چپ انتخاب کنید و سپس در ناوبری سمت راست گزینه Background را انتخاب کنید که یک کادر محاوره‌ای انتخاب رنگ را باز می‌کند.

صفحه آغازین
برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

نکته: اگر گزینه دوم را در کادر انتخاب رنگ انتخاب کرده و سپس RGB Sliders را کلیک کنید، می‌توانید مقادیر عددی هگزادسیمال نیز وارد کنید.

صفحه آغازین

در ادامه رنگ پس‌زمینه را به صورت #4F6D7A تعیین کنید.

سپس باید یک Image View به صفحه آغازین خود اضافه کنیم. این مورد را می‌توانید با فشردن گزینه سوم منوی پایین-راست و جستجو به دنبال image بیابید. زمانی که یافتید، آن را روی View آبی‌رنگ بکشید.

صفحه آغازین
برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

سپس منبع تصویر را از سمت راست-بالا انتخاب کنید. زمانی که تصویر را انتخاب می‌کنید، همه تصاویر منوی بازشدنی Images.xcassets را نمایش دهید و گزینه SplashIcon را انتخاب کنید.

صفحه آغازین
برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

اکنون برای اصلاح نسبت‌ها، Content Mode را روی Aspect Fit قرار دهید. این گزینه در منوی سمت راست و در جایگاه دوم از پایین قرار دارد.

صفحه آغازین
برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

سپس باید مطمئن شویم که آیکون ما صرف‌نظر از این که اپلیکیشن روی کدام دستگاه اجرا شده است، در مرکز صفحه باقی می‌ماند. به این منظور در ناوبری سمت راست، آیکون پنجم از بالا (که شبیه خط کش است) را انتخاب کنید.

صفحه آغازین
برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

درون بخش Autoresizing باید خطوط قرمز بیرون را غیرفعال و خطوط قرمز درونی را فعال کنید. بدین ترتیب تصویر می‌تواند صرف‌نظر از این که ابعاد صفحه چه قدر است در مرکز آن بماند.

صفحه آغازین

بدین ترتیب نتیجه زیر به دست می‌آید:

صفحه آغازین

اینک باید به بررسی مشکل چشمک زدن صفحه سفید بپردازیم.

اما قبل از آن باید بفهمیم دلیل این مسئله چیست. این وضعیت زمانی اتفاق می‌افتد که جاوا اسکریپت در حال بارگذاری است و bridge مقداردهی اولیه می‌شود. یا دست‌کم این توضیحی است که ما به آن رسیده‌ایم. صفحه آغازین زمانی نمایش می‌یابد که اپلیکیشن در حال بالا آمدن است (React Native). سپس هنگامی که React Native مقداردهی می‌شود آن صفحه سفید را می‌بینیم، بنابراین باید صفحه آغازین را مقداری بیش از آنچه که لازم است روی صفحه حفظ کنیم. بدین منظور از react-native-splash-screen استفاده می‌کنیم. ابتدا این پکیج را نصب کرده و آن را لینک کنید:

yarn add react-native-splash-screen@3.0.6

react-native link react-native-splash-screen

سپس باید پکیج را پیکربندی کنیم. به این منظور در Xcode فایل AppDelegate.m را باز می‌کنیم.

سپس "import “SplashScreen.h# را با ایمپورت‌های دیگر اضافه می‌کنیم و در ادامه ;[SplashScreen show] را در متد didFinishLaunchingWithOptions درست بالاتر از ;return YES اضافه می‌کنیم.

صفحه آغازین
برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

در نهایت در App.js باید به صفحه آغازین اعلام کنیم که وقتی اپلیکیشن ما آماده شد پنهان شود. این کار را در قلاب چرخه عمر componentDidMount انجام می‌دهیم.

1import SplashScreen from 'react-native-splash-screen';
2
3export default class App extends Component {
4  componentDidMount() {
5    SplashScreen.hide()
6  }
7
8  ...
9}

صفحه آغازین

اینک ظاهر آن بهبود زیادی یافته است. در ادامه می‌خواهیم وقتی اپلیکیشن در صفحه آغازین قرار دارد، رنگ نوار وضعیت به صورت روشن در آید. به این منظور Info.plist را در Xcode باز کنید و یک ردیف جدید به آن بیفزایید. در این ردیف کلید باید به صورت UIStatusBarStyle و مقدار (رشته‌ای) به صورت UIStatusBarStyleLightContent باشد.

صفحه آغازین
برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

بدین ترتیب نتیجه مناسب زیر به دست می‌آید:

صفحه آغازین

افزودن صفحه آغازین به اندروید

بخش اندروید بسیار پیچیده‌تر از iOS است، زیرا باید دو صفحه آغازین ایجاد کنیم. یکی به وسیله react-native-splash-screen استفاده می‌شود و دیگری پیش از آن که اپلیکیشن inflate شود مورد استفاده قرار می‌گیرد.

نخستین کاری که باید انجام دهیم این است که فایل‌های تصویر را که قبلاً دانلود کرده‌ایم به دایرکتوری‌های mipmap در پروژه اندروید اضافه کنیم. اندروید چگالی‌های پیکسلی متفاوت را به روشی متفاوت از iOS مدیریت می‌کند و از این رو باید برخی تغییرات در تصاویر ایجاد کنیم.

قبل از هر چیز پوشه‌های mipmap در android/app/src/main/res قرار دارند و چگالی پیکسلی تصاویر هر کدام بر اساس نام پوشه متفاوت است. تصاویر ما باید به صورت زیر قرار گیرند:

  • mipmap-mdpi = icon.png
  • mipmap-hdpi = icon@2x.png
  • mipmap-xhdpi = icon@3x.png
  • mipmap-xxhdpi = icon@3x.png

زمانی که فایل‌ها در پوشه‌های مربوطه قرار گرفتند باید نام آن‌ها را به icon.png تغییر دهید.

صفحه آغازین

سپس پا را فراتر گذارده و صفحه آغازین را که هنگام لانچ شدن اولیه اپلیکیشن از آغاز سرد نمایش می‌یابد، ایجاد می‌کنیم.

ابتدا یک فایل به نام background_splash.xml file در android/app/src/main/res/drawable ایجاد می‌کنیم. احتمالاً باید دایرکتوری مربوطه را نیز بسازید. کد زیر را به فایل اضافه کنید:

1<?xml version="1.0" encoding="utf-8"?>
2<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3
4    <item
5        android:drawable="@color/blue"/>
6
7    <item
8        android:width="200dp"
9        android:height="200dp"
10        android:drawable="@mipmap/icon"
11        android:gravity="center" />
12
13</layer-list>
صفحه آغازین
برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

کاری که در اینجا انجام می‌دهیم این است که یک فهرست لایه‌ها به نام layer-list تنظیم می‌کنیم و سپس یک رنگ پس‌زمینه تعیین می‌کنیم و در نهایت آیکون خود را رندر می‌کنیم. این آیکون روی صفحه 200dp عرض و ارتفاع خواهد داشت.

سپس فایلی به نام colors.xml در android/app/src/main/res/values می‌سازیم که در آن رنگ آبی خود را تعریف می‌کنیم.

1<?xml version="1.0" encoding="utf-8"?>
2<resources>
3    <color name="blue">#4F6D7A</color>
4</resources>

در ادامه یک مقدار جدید به نام SplashTheme در android/app/src/main/res/values/styles.xml می‌سازیم.

1<style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
2    <item name="android:windowBackground">@drawable/background_splash</item>
3    <item name="android:statusBarColor">@color/blue</item>
4</style>

به آن اعلام خواهیم کرد که از background_splash که به صورت پس‌زمینه پنجره تعریف کرده‌ایم استفاده کند و همچنین اعلام می‌کنیم که از رنگ آبی برای نوار وضعیت بهره بگیرد. ما تلاش می‌کنیم اپلیکیشن واقعی را تا حد امکان در اینجا شبیه‌سازی کنیم و از این رو تغییر نوار وضعیت را طراحی می‌کنیم.

حال که به اینجا رسیده‌ایم پا را فراتر گذارده و مطمئن می‌شویم که StatusBar پیش‌فرض قالب اصلی اپلیکیشن ما دارای رنگ پیش‌فرض صحیحی است. بدین ترتیب فایل styles.xml باید به صورت زیر باشد:

1<resources>
2
3    <!-- Base application theme. -->
4    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
5        <!-- Customize your theme here. -->
6        <item name="android:statusBarColor">@color/blue</item>
7    </style>
8
9    <style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
10        <item name="android:windowBackground">@drawable/background_splash</item>
11        <item name="android:statusBarColor">@color/blue</item>
12    </style>
13
14</resources>

اکنون باید به اپلیکیشن خود اعلام کنیم که در زمان مقدر دهی اولیه از SplashTheme استفاده کند. این کار را در AndroidManifest.xml انجام می‌دهیم. درون <application></application> کد زیر را اضافه می‌کنیم:

1<activity
2    android:name=".SplashActivity"
3    android:theme="@style/SplashTheme"
4    android:label="@string/app_name">
5    <intent-filter>
6        <action android:name="android.intent.action.MAIN" />
7        <category android:name="android.intent.category.LAUNCHER" />
8    </intent-filter>
9</activity>

و MainActivity را طوری تغییر می‌دهیم که به صورت زیر در آید. توجه ویژه‌ای به android:exported="true"‎ که اضافه می‌کنیم داشته باشید:

1<activity
2  android:name=".MainActivity"
3  android:label="@string/app_name"
4  android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
5  android:windowSoftInputMode="adjustResize"
6  android:exported="true"
7/>

بدین ترتیب فایل AndroidManifest.xml به صورت زیر درمی‌آید:

1<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2    package="com.splashexample"
3    android:versionCode="1"
4    android:versionName="1.0">
5
6    <uses-permission android:name="android.permission.INTERNET" />
7    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
8
9    <uses-sdk
10        android:minSdkVersion="16"
11        android:targetSdkVersion="22" />
12
13    <application
14      android:name=".MainApplication"
15      android:allowBackup="true"
16      android:label="@string/app_name"
17      android:icon="@mipmap/ic_launcher"
18      android:theme="@style/AppTheme">
19
20        <activity
21            android:name=".SplashActivity"
22            android:theme="@style/SplashTheme"
23            android:label="@string/app_name">
24            <intent-filter>
25                <action android:name="android.intent.action.MAIN" />
26                <category android:name="android.intent.category.LAUNCHER" />
27            </intent-filter>
28        </activity>
29
30        <activity
31          android:name=".MainActivity"
32          android:label="@string/app_name"
33          android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
34          android:windowSoftInputMode="adjustResize"
35          android:exported="true"
36        />
37
38      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
39    </application>
40
41</manifest>

اکنون باید یک فایل به نام SplashActivity.java ایجاد کنیم.

صفحه آغازین
برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

هدف از این فایل SplashActivity.java آن است که به MainActivity فوروارد شود. محتوای آن چنین است:

1package com.splashexample; // make sure this is your package name
2
3import android.content.Intent;
4import android.os.Bundle;
5import android.support.v7.app.AppCompatActivity;
6
7public class SplashActivity extends AppCompatActivity {
8    @Override
9    protected void onCreate(Bundle savedInstanceState) {
10        super.onCreate(savedInstanceState);
11
12        Intent intent = new Intent(this, MainActivity.class);
13        startActivity(intent);
14        finish();
15    }
16}

اکنون فرض می‌کنیم که همه چیز به درستی تنظیم شده است. اگر اپلیکیشن را اجرا کنید و سپس از آن خارج شوید (تا یک آغاز سرد داشته باشیم)، باید چیزی مانند زیر ببینید:

صفحه آغازین

این وضعیت مناسبی است، اما آن صفحه سفید هنوز دیده می‌شود. البته اصلاح آن به سادگی iOS نیست، اما چندان دشوار هم نیست. اگر react-native-splash-screen را قبلاً نصب نکرده‌اید، آن را نصب کرده و لینک کنید.

yarn add react-native-splash-screen@3.0.6
react-native link

سپس باید سمت اندروید نیتیو را پیکربندی کنید. در فایل MainActivity.java کد زیر را اضافه کنید:

1package com.splashexample; // this should be your package name
2
3import com.facebook.react.ReactActivity;
4import org.devio.rn.splashscreen.SplashScreen; // import this
5import android.os.Bundle; // import this
6
7public class MainActivity extends ReactActivity {
8    @Override
9    protected void onCreate(Bundle savedInstanceState) {
10        SplashScreen.show(this);  // here
11        super.onCreate(savedInstanceState);
12    }
13
14    ...
15}

سپس App.js را در اپلیکیشن خود طوری پیکربندی کنید که به محض بارگذاری شدن اپلیکیشن، صفحه آغازین را ببندد.

1import SplashScreen from 'react-native-splash-screen';
2
3export default class App extends Component {
4  componentDidMount() {
5    SplashScreen.hide()
6  }
7
8  ...
9}

سپس باید فایلی به نام launch_screen.xml (حتماً باید به این نام باشد) درون android/app/src/main/res/layout ایجاد کنید که عنصر ریشه‌اش LinearLayout باشد.

صفحه آغازین
فایل لی‌آوت جدید - برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.
صفحه آغازین
ایجاد با LinearLayout - برای مشاهده تصویر در اندازه اصلی روی آن کلیک کنید.

اندروید استودیو اینترفیسی بسیار شبیه به اینترفیس‌ساز Xcode دارد، اما در این راهنما ترجیح می‌دهیم، عناصر را مستقیماً تغییر دهیم. ابتدا gravity عنصر LinearLayout را طوری تنظیم می‌کنیم که در مرکز قرار گیرد و رنگ پس‌زمینه‌اش نیز آبی باشد. بقیه قسمت‌ها به صورت پیش‌فرض می‌ماند.

1<?xml version="1.0" encoding="utf-8"?>
2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3    android:orientation="vertical"
4    android:layout_width="match_parent"
5    android:layout_height="match_parent"
6    android:background="@color/blue"
7    android:gravity="center">
8</LinearLayout>

سپس ImageView را طوری رندر می‌کنیم که آیکونی درون LinearLayout نمایش دهد.

1<?xml version="1.0" encoding="utf-8"?>
2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3    android:orientation="vertical"
4    android:layout_width="match_parent"
5    android:layout_height="match_parent"
6    android:background="@color/blue"
7    android:gravity="center">
8    <ImageView
9        android:layout_width="200dp"
10        android:layout_height="200dp"
11        android:layout_marginTop="24dp"
12        android:src="@mipmap/icon"
13    />
14</LinearLayout>

نکاتی در خصوص مشخصه‌های روی ImageView

  • android:layout_width و android:layout_height – ارتفاع و عرض را تعیین می‌کنند. این مقادیر باید همانند مقادیری باشند که در background_splash.xml تنظیم شده‌اند.
  • android:layout_marginTop – این ارتفاع نوار وضعیت است. اگر این مقدار را نادیده بگیریم، آیکون‌ها دقیقاً در همان نقطه مورد نظر نخواهند بود و یک پرش در زمان تغییر صفحه آغازین را شاهد خواهید بود.
  • "android:src="@mipmap/icon – تصویری است که باید رندر شود.

در نهایت درون فایل colors.xml کد زیر را اضافه کنید:

1<color name="primary_dark">#4F6D7A</color>

در غیر این صورت اپلیکیشن کرش می‌کند. این یک باگ در react-native-splash-screen است و احتمالاً در نسخه‌های بعدی رفع خواهد شد.

صفحه آغازین

بدین ترتیب به پایان این مقاله می‌رسیم. امیدواریم این راهنما برای شما کاربردی بوده باشد.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۱ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
handlebar-labs
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *