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

الإنشاء بشكل أفضل باستخدام 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 تنشئه كعرض الخلفية أو فارغًا إذا لم تكن هناك حاجة إلى عرض الخلفية.
  • تعرض onCreateContentView() عنصر View الذي تنشئه ليكون بمثابة عرض المحتوى أو يعرض قيمة فارغة إذا لم تكن هناك حاجة إلى عرض المحتوى.
  • تعرض السمة 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 لفترة وجيزة، ثم يتلاشى Drawable قبل عرض الصفحة الأولى من OnboardingSupportFragment.

إذا أردت توفير صورة متحركة مخصّصة لشاشة شعارك، بدلاً من استدعاء 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;
    }