تعريف المستخدمين لأول مرة على تطبيقك

إنشاء تطبيقات أفضل باستخدام Compose
يمكنك إنشاء واجهات مستخدم رائعة بأقل قدر من الرموز البرمجية باستخدام Jetpack Compose لنظام التشغيل Android TV.

لعرض معلومات إرشادية للمستخدمين الجدد عند بدء تشغيل التطبيق، وذلك لمساعدتهم على الاستفادة إلى أقصى حد من تطبيقك. في ما يلي بعض الأمثلة على المعلومات التي يجب تقديمها عند إعداد الحساب:

  • عرض معلومات مفصّلة حول القنوات المتاحة عندما يصل المستخدم إلى تطبيق قناة للمرة الأولى
  • جذب الانتباه إلى الميزات الجديرة بالذكر في تطبيقك
  • وضِّح أي خطوات مطلوبة أو مقترَحة على المستخدمين اتّخاذها عند استخدام التطبيق للمرة الأولى.

توفّر مكتبة androidx.leanback الفئة OnboardingSupportFragment لعرض معلومات المستخدمين لأول مرة. يوضّح هذا الدليل كيفية استخدام فئة OnboardingSupportFragment لعرض معلومات تمهيدية تظهر عند تشغيل التطبيق للمرة الأولى.

تستخدم OnboardingSupportFragment أفضل الممارسات لواجهة مستخدم التلفزيون لعرض المعلومات بطريقة تتوافق مع أنماط واجهة مستخدم التلفزيون ويسهل التنقّل فيها على أجهزة التلفزيون.

الشكل 1. مثال OnboardingSupportFragment

لا يكون OnboardingSupportFragment مناسبًا لكل حالات الاستخدام. لا تستخدِم OnboardingSupportFragment عندما تحتاج إلى تضمين عناصر واجهة مستخدم تتطلّب إدخال بيانات من المستخدم، مثل الأزرار والحقول. يجب أيضًا عدم استخدام OnboardingSupportFragment للمهام التي سيجريها المستخدم بانتظام. أخيرًا، إذا كنت بحاجة إلى عرض واجهة مستخدم متعددة الصفحات تتطلب إدخال بيانات من المستخدم، ننصحك باستخدام GuidedStepSupportFragment.

إضافة OnboardingSupportFragment

لإضافة OnboardingSupportFragment إلى تطبيقك، عليك تنفيذ فئة توسّع الفئة OnboardingSupportFragment. أضِف هذا الجزء إلى نشاط، إما باستخدام ملف XML لتصميم النشاط أو بشكل آلي. تأكَّد من أنّ النشاط أو الجزء يستخدم تصميمًا مشتقًا من Theme_Leanback_Onboarding، كما هو موضّح في قسم تخصيص التصاميم.

في طريقة onCreate() الخاصة بالنشاط الرئيسي لتطبيقك، استدعِ startActivity() باستخدام Intent يشير إلى النشاط الرئيسي OnboardingSupportFragment. يساعد ذلك في ضمان ظهور OnboardingSupportFragment فور بدء تشغيل تطبيقك.

للمساعدة في ضمان عدم ظهور الإعلان OnboardingSupportFragment إلا في المرة الأولى التي يبدأ فيها المستخدم تطبيقك، استخدِم عنصر SharedPreferences لتتبُّع ما إذا كان المستخدم قد شاهد الإعلان OnboardingSupportFragment من قبل. حدِّد قيمة منطقية تتغيّر إلى "صحيح" عندما ينتهي المستخدم من عرض OnboardingSupportFragment. تحقَّق من هذه القيمة في طريقة onCreate() لنشاطك الرئيسي، ولا تبدأ نشاط OnboardingSupportFragment الرئيسي إلا إذا كانت القيمة غير صحيحة.

يعرض المثال التالي عملية إلغاء onCreate() تتحقّق من قيمة SharedPreferences، وإذا لم يتم ضبطها على "صحيح"، يتم استدعاء startActivity() لعرض OnboardingSupportFragment:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    PreferenceManager.getDefaultSharedPreferences(this).apply {
        // Check if we need to display our OnboardingSupportFragment
        if (!getBoolean(MyOnboardingSupportFragment.COMPLETED_ONBOARDING_PREF_NAME, false)) {
            // The user hasn't seen the OnboardingSupportFragment yet, so show it
            startActivity(Intent(this@OnboardingActivity, OnboardingActivity::class.java))
        }
    }
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    SharedPreferences sharedPreferences =
            PreferenceManager.getDefaultSharedPreferences(this);
    // Check if we need to display our OnboardingSupportFragment
    if (!sharedPreferences.getBoolean(
            MyOnboardingSupportFragment.COMPLETED_ONBOARDING_PREF_NAME, false)) {
        // The user hasn't seen the OnboardingSupportFragment yet, so show it
        startActivity(new Intent(this, OnboardingActivity.class));
    }
}

بعد أن يشاهد المستخدم OnboardingSupportFragment، ضع علامة "تمت المشاهدة" عليه باستخدام العنصر SharedPreferences. لإجراء ذلك، عليك إلغاء onFinishFragment() في OnboardingSupportFragment وضبط قيمة SharedPreferences على "صحيح"، كما هو موضّح في المثال التالي:

Kotlin

override fun onFinishFragment() {
    super.onFinishFragment()
    // User has seen OnboardingSupportFragment, so mark our SharedPreferences
    // flag as completed so that we don't show our OnboardingSupportFragment
    // the next time the user launches the app
    PreferenceManager.getDefaultSharedPreferences(context).edit().apply {
        putBoolean(COMPLETED_ONBOARDING_PREF_NAME, true)
        apply()
    }
}

Java

@Override
protected void onFinishFragment() {
    super.onFinishFragment();
    // User has seen OnboardingSupportFragment, so mark our SharedPreferences
    // flag as completed so that we don't show our OnboardingSupportFragment
    // the next time the user launches the app
    SharedPreferences.Editor sharedPreferencesEditor =
            PreferenceManager.getDefaultSharedPreferences(getContext()).edit();
    sharedPreferencesEditor.putBoolean(
            COMPLETED_ONBOARDING_PREF_NAME, true);
    sharedPreferencesEditor.apply();
}

إضافة صفحات OnboardingSupportFragment

تعرض OnboardingSupportFragment المحتوى في سلسلة من الصفحات المنظَّمة. بعد إضافة OnboardingSupportFragment، عليك تحديد صفحات الإعداد. يمكن أن تتضمّن كل صفحة عنوانًا ووصفًا وعدة طرق عرض فرعية يمكن أن تحتوي على صور أو رسوم متحركة.

الشكل 2. OnboardingSupportFragment عناصر الصفحة

تعرض "الشكل 2" مثالاً لصفحة تتضمّن وسائل شرح تحدّد عناصر الصفحة القابلة للتخصيص التي يمكن أن توفّرها OnboardingSupportFragment. عناصر الصفحة هي:

  1. تمثّل هذه السمة عنوان الصفحة.
  2. تمثّل هذه السمة وصف الصفحة.
  3. عرض محتوى الصفحة، وفي هذه الحالة علامة اختيار خضراء بسيطة في مربّع رمادي طريقة العرض هذه اختيارية. استخدِم طريقة العرض هذه لتوضيح تفاصيل الصفحة. على سبيل المثال، يمكنك تضمين لقطة شاشة تسلّط الضوء على ميزة التطبيق التي تصفها الصفحة.
  4. طريقة عرض خلفية الصفحة، وهي في هذه الحالة تدرّج بسيط باللون الأزرق يتم عرض طريقة العرض هذه دائمًا خلف طرق العرض الأخرى على الصفحة. طريقة العرض هذه اختيارية.
  5. عرض المقدّمة في الصفحة، وهو شعار في هذه الحالة يتم عرض طريقة العرض هذه دائمًا في مقدّمة جميع طرق العرض الأخرى على الصفحة. طريقة العرض هذه اختيارية.

يجب تهيئة معلومات الصفحة عند إنشاء OnboardingSupportFragment لأول مرة أو ربطها بالنشاط الرئيسي، لأنّ النظام يطلب معلومات الصفحة عند إنشاء طريقة عرض الجزء. يمكنك تهيئة معلومات الصفحة في أداة إنشاء الفئة أو في عملية إلغاء onAttach().

تجاوز كلّ من الطرق التالية التي تقدّم معلومات الصفحة إلى النظام:

  • تعرض السمة getPageCount() عدد الصفحات في OnboardingSupportFragment.
  • تعرض getPageTitle() عنوان رقم الصفحة المطلوب.
  • تعرض getPageDescription() وصفًا لرقم الصفحة المطلوب.

يمكنك تجاهل كل طريقة من الطرق التالية لتوفير طرق عرض فرعية اختيارية لعرض الصور أو الرسوم المتحركة:

  • تعرض الدالة onCreateBackgroundView() القيمة View التي تنشئها لتعمل كطريقة العرض في الخلفية أو تعرض القيمة null إذا لم تكن هناك حاجة إلى طريقة عرض في الخلفية.
  • تعرض الدالة onCreateContentView() القيمة View التي تنشئها لتعمل كطريقة عرض المحتوى أو القيمة null إذا لم تكن هناك حاجة إلى طريقة عرض المحتوى.
  • onCreateForegroundView() تعرض View التي تنشئها لتعمل كطريقة عرض في المقدّمة أو تعرض قيمة فارغة إذا لم تكن هناك حاجة إلى طريقة عرض في المقدّمة.

يضيف النظام View الذي تنشئه إلى تخطيط الصفحة. يستبدل المثال التالي onCreateContentView() ويعرض ImageView:

Kotlin

private lateinit var contentView: ImageView
...
override fun onCreateContentView(inflater: LayoutInflater?, container: ViewGroup?): View? {
    return ImageView(context).apply {
        scaleType = ImageView.ScaleType.CENTER_INSIDE
        setImageResource(R.drawable.onboarding_content_view)
        setPadding(0, 32, 0, 32)
        contentView = this
    }
}

Java

private ImageView contentView;
...
@Override
protected View onCreateContentView(LayoutInflater inflater, ViewGroup container) {
    contentView = new ImageView(getContext());
    contentView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
    contentView.setImageResource(R.drawable.onboarding_content_view);
    contentView.setPadding(0, 32, 0, 32);
    return contentView;
}

إضافة شاشة شعار أولية

يمكن أن يبدأ OnboardingSupportFragment بشاشة شعار اختيارية تعرّف المستخدمين على تطبيقك. إذا أردت عرض Drawable كشاشة شعار، استخدِم setLogoResourceId() مع معرّف Drawable في طريقة onCreate() الخاصة بـ OnboardingSupportFragment. يظهر Drawable تدريجيًا ويتم عرضه لفترة وجيزة، ثم يختفي تدريجيًا قبل عرض الصفحة الأولى من OnboardingSupportFragment.Drawable

إذا أردت توفير صورة متحركة مخصّصة لشاشة شعارك بدلاً من استدعاء setLogoResourceId()، يمكنك إلغاء onCreateLogoAnimation() وعرض عنصر Animator يعرض الصورة المتحركة المخصّصة، كما هو موضّح في المثال التالي:

Kotlin

public override fun onCreateLogoAnimation(): Animator =
        AnimatorInflater.loadAnimator(context, R.animator.onboarding_logo_screen_animation)

Java

@Override
public Animator onCreateLogoAnimation() {
    return AnimatorInflater.loadAnimator(getContext(),
            R.animator.onboarding_logo_screen_animation);
}

تخصيص الرسوم المتحركة للصفحة

يستخدم النظام رسومًا متحركة تلقائية عند عرض الصفحة الأولى من OnboardingSupportFragment وعندما ينتقل المستخدم إلى صفحة أخرى. يمكنك تخصيص هذه الرسوم المتحركة من خلال إلغاء الطرق في OnboardingSupportFragment.

لتخصيص الرسوم المتحركة التي تظهر على صفحتك الأولى، استبدِل onCreateEnterAnimation() وعُد Animator. ينشئ المثال التالي Animator يغيّر حجم عرض المحتوى أفقيًا:

Kotlin

override fun onCreateEnterAnimation(): Animator =
    ObjectAnimator.ofFloat(contentView, View.SCALE_X, 0.2f, 1.0f)
            .setDuration(ANIMATION_DURATION)

Java

@Override
protected Animator onCreateEnterAnimation() {
    Animator startAnimator = ObjectAnimator.ofFloat(contentView,
            View.SCALE_X, 0.2f, 1.0f).setDuration(ANIMATION_DURATION);
    return startAnimator;
}

لتخصيص الحركة المستخدَمة عند انتقال المستخدم إلى صفحة أخرى، عليك إلغاء onPageChanged(). في طريقتك onPageChanged()، أنشئ عناصر Animator تزيل الصفحة السابقة وتعرض الصفحة التالية، وأضِفها إلى AnimatorSet، وشغِّل المجموعة. يستخدم المثال التالي صورة متحركة تتلاشى لإزالة الصفحة السابقة، ويعدّل صورة عرض المحتوى، ويستخدم صورة متحركة تتلاشى تدريجيًا لعرض الصفحة التالية:

Kotlin

override fun onPageChanged(newPage: Int, previousPage: Int) {
    // Create a fade-out animation for previousPage and, once
    // done, swap the contentView image with the next page's image
    val fadeOut = ObjectAnimator.ofFloat(mContentView, View.ALPHA, 1.0f, 0.0f)
            .setDuration(ANIMATION_DURATION)
            .apply {
                addListener(object : AnimatorListenerAdapter() {

                    override fun onAnimationEnd(animation: Animator) {
                        mContentView.setImageResource(pageImages[newPage])
                    }
                })
            }
    // Create a fade-in animation for nextPage
    val fadeIn = ObjectAnimator.ofFloat(mContentView, View.ALPHA, 0.0f, 1.0f)
            .setDuration(ANIMATION_DURATION)
    // Create AnimatorSet with fade-out and fade-in animators and start it
    AnimatorSet().apply {
        playSequentially(fadeOut, fadeIn)
        start()
    }
}

Java

@Override
protected void onPageChanged(final int newPage, int previousPage) {
    // Create a fade-out animation for previousPage and, once
    // done, swap the contentView image with the next page's image
    Animator fadeOut = ObjectAnimator.ofFloat(mContentView,
            View.ALPHA, 1.0f, 0.0f).setDuration(ANIMATION_DURATION);
    fadeOut.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            mContentView.setImageResource(pageImages[newPage]);
        }
    });
    // Create a fade-in animation for nextPage
    Animator fadeIn = ObjectAnimator.ofFloat(mContentView,
            View.ALPHA, 0.0f, 1.0f).setDuration(ANIMATION_DURATION);
    // Create AnimatorSet with fade-out and fade-in animators and start it
    AnimatorSet set = new AnimatorSet();
    set.playSequentially(fadeOut, fadeIn);
    set.start();
}

لمزيد من التفاصيل حول كيفية إنشاء عناصر Animator وعناصر AnimatorSet، راجِع نظرة عامة على "حركة العناصر".

تخصيص المظاهر

يجب أن يستخدم أي تنفيذ OnboardingSupportFragment إما المظهر Theme_Leanback_Onboarding أو مظهرًا موروثًا من Theme_Leanback_Onboarding. اضبط سمة OnboardingSupportFragment من خلال تنفيذ أحد الإجراءات التالية:

  • اضبط نشاط العنصر الرئيسي OnboardingSupportFragment لاستخدام المظهر المطلوب. يوضّح المثال التالي كيفية ضبط نشاط لاستخدام Theme_Leanback_Onboarding في ملف بيان التطبيق:
    <activity
       android:name=".OnboardingActivity"
       android:enabled="true"
       android:exported="true"
       android:theme="@style/Theme.Leanback.Onboarding">
    </activity>
  • اضبط المظهر في النشاط الرئيسي باستخدام السمة LeanbackOnboardingTheme_onboardingTheme في مظهر نشاط مخصّص. أشِر بهذه السمة إلى مظهر مخصّص آخر تستخدمه فقط عناصر OnboardingSupportFragment في نشاطك. استخدِم هذا الأسلوب إذا كان نشاطك يستخدم حاليًا مظهرًا مخصّصًا ولا تريد تطبيق أنماط OnboardingSupportFragment على طرق العرض الأخرى في النشاط.
  • استبدِل onProvideTheme() المظهر الحالي بالمظهر المطلوب. استخدِم هذا الأسلوب إذا كانت أنشطة متعدّدة تستخدم OnboardingSupportFragment أو إذا كان النشاط الرئيسي لا يمكنه استخدام المظهر المطلوب. يستبدل المثال التالي onProvideTheme() ويعرض Theme_Leanback_Onboarding:

    Kotlin

    override fun onProvideTheme(): Int = R.style.Theme_Leanback_Onboarding

    Java

    @Override
    public int onProvideTheme() {
       return R.style.Theme_Leanback_Onboarding;
    }