تتبُّع مستوى العرض في Compose

يُعدّ تتبُّع ظهور عنصر في واجهة المستخدم على الشاشة مفيدًا في مجموعة متنوعة من حالات الاستخدام، مثل تسجيل الإحصاءات وإدارة حالة واجهة المستخدم وتحسين الموارد من خلال تشغيل محتوى الفيديو أو إيقافه مؤقتًا تلقائيًا. يوفّر Compose عدة عناصر تعديل لتتبُّع مستوى ظهور عناصر في واجهة المستخدم، مثل:

  • ‫onVisibilityChanged: يُعلمك هذا المُعدِّل عندما يتغيّر مستوى ظهور دالة مركّبة. وهي مثالية لتشغيل إجراء أو تأثير جانبي في كل مرة تصبح فيها الدالة المركّبة مرئية.
  • ‫onLayoutRectChanged: يوفّر هذا المُعدِّل معلومات عن حدود الدالة المركّبة بالنسبة إلى الجذر والنافذة والشاشة. وتوفّر هذه الواجهة تحكّمًا منخفض المستوى، وهي واجهة برمجة التطبيقات الأساسية لـ onVisibilityChanged. يشبه هذا المُعدِّل onGloballyPositioned، ولكنّه يقدّم أداءً أفضل ومرونة أكبر.

يمكنك استخدام واجهات برمجة التطبيقات هذه مع أي دالة مركّبة كجزء من سلسلة المُعدِّلات.

تتبُّع التغييرات في مستوى الظهور باستخدام onVisibilityChanged

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

لتلقّي إشعار عند تغيير مستوى ظهور عنصر، استخدِم المُعدِّل onVisibilityChanged، كما هو موضّح في المثال التالي:

Text(
    text = "Some text",
    modifier = Modifier
        .onVisibilityChanged { visible ->
            if (visible) {
                // Do something if visible.
            } else {
                // Do something if not visible.
            }
        }
        .padding(vertical = 8.dp)
)

يوفّر المُعدِّل onVisibilityChanged قيمة منطقية تعكس حالة الظهور الحالية للدالة المركّبة. بالإضافة إلى ذلك، يوفّر هذا الحدث مَعلمات مثل minFractionVisible وminDurationMs، ما يمنحك تحكّمًا أكثر دقة في وقت تفعيل دالة الاستدعاء الخاصة بإمكانية العرض.

مثل أي معدِّل آخر، يُعدّ التسلسل مهمًا مع معدِّل onVisibilityChanged. يوضّح المثال السابق دالة مركّبة تعرض نصًا مع مساحة متروكة. للتأكّد من أنّ المُعدِّل يؤثر في الدالة المركّبة بالكامل مع الحشو، أضِف المُعدِّل onVisibilityChanged قبل المُعدِّل padding.

ضبط حدّ زمني على دالة مركّبة قبل تفعيل دالة الاستدعاء الخاصة بمستوى الظهور

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

لتشغيل إجراء بعد أن يصبح العنصر مرئيًا لفترة محدّدة، استخدِم المَعلمة minDurationMs في المُعدِّل onVisibilityChanged. تحدّد هذه المَعلمة الحدّ الأدنى من الوقت الذي يجب أن تكون فيه الدالة المركّبة مرئية بشكل مستمر ليتم تفعيل دالة الاستدعاء. إذا توقّفت الدالة المركّبة عن الظهور قبل انتهاء المدة، تتم إعادة ضبط الموقّت. القيمة التلقائية هي 0 مللي ثانية.

يغيّر المقتطف التالي الخلفية إلى اللون الأرجواني بعد أن تظهر الدالة المركّبة للمستخدم لمدة 3 ثوانٍ:

var background by remember { mutableStateOf(PalePink) }
Card(
    modifier = modifier
        // ...
        .onVisibilityChanged(minDurationMs = 3000) {
            if (it) {
                background = MutedPlum
            }
        }
) {

    Box(
        modifier = Modifier
            // ...
            .background(background),
        contentAlignment = Alignment.Center,
    ) {
        // ...
    }
}

الشكل 1: تتغيّر الخلفية من اللون الوردي إلى اللون البرقوقي بعد ظهور الدالة المركّبة على الشاشة لمدة 3 ثوانٍ متواصلة.

ضبط الحدّ الأدنى للجزء المرئي

يُعدّ ضبط الحد الأدنى للجزء المرئي من دالة الاستدعاء الخاصة بإمكانية ظهور الدالة المركّبة مفيدًا عند التعامل مع المحتوى القابل للتمرير (مثل LazyColumn) لتحسين عملية جلب البيانات للعناصر التي تتجاوز حجم الشاشة.

في هذه الحالات، استخدِم المَعلمة minFractionVisible في المُعدِّل onVisibilityChanged لتحديد الجزء الذي يجب أن يظهر على الشاشة لكي يتم وضع علامة على الدالة المركّبة على أنّها مرئية. تتراوح القيم العائمة المسموح بها بين 0.0f و1.0f، ويتم ضبطها على 1.0f تلقائيًا. تشير السمة 1.0f إلى أنّ الدالة المركّبة يجب أن تكون مرئية بالكامل على الشاشة، أو أن تملأ إطار العرض بالكامل إذا كانت أكبر منه.

تتلقّى دالة الاستدعاء true عندما يكون الجزء المرئي أكبر من minFractionVisible، أو عندما تكون الدالة المركّبة مرئية بالكامل أو تملأ إطار العرض. وإذا لم يكن الأمر كذلك، فستتلقّى false.

LazyColumn(
    modifier = modifier.fillMaxSize()
) {
    item {
        Box(
            modifier = Modifier
                // ...
                // Here `visible` is `true` when more than 20% of the composable is visible.
                .onVisibilityChanged(
                    minFractionVisible = 0.2f,
                ) { visible ->
                    if (visible) {
                        // Call specific logic here.
                        // viewModel.fetchDataFromNetwork()
                    }
                }
                .padding(vertical = 16.dp)
        ) {
            Text(
                text = "Sample Text",
                modifier = Modifier.padding(horizontal = 16.dp)
            )
        }
    }
}

الشكل 2: بدون ضبط minFractionVisible. الشكل 3: مع ضبط minFractionVisible على 0.2f.

يستخدم المثال السابق تحميل Androidify Bots مسبقًا من الشبكة قبل أن تصبح الدالة المركّبة مرئية بالكامل. في الشكل 2، لا يتم تحميل الروبوت الثالث، لأنّ الدالة المركّبة غير مرئية بالكامل. في الشكل 3، تم ضبط السمة minFractionVisible، ويتم تحميل برنامج التتبُّع الثالث قبل أن يصبح مرئيًا بالكامل على الشاشة.

إخفاء دالة مركّبة والاحتفاظ بمساحتها

لإخفاء دالة مركّبة بدون تغيير التنسيق المحيط بها، استخدِم المُعدِّل visible. عند ضبط القيمة على false، سيتم قياس الدالة المركّبة ولكن لن يتم وضعها أو رسمها. على عكس ضبط alpha على 0f، يؤدي visible(false) أيضًا إلى إزالة العنصر من شجرة تسهيل الاستخدام وإيقاف تفاعلات اللمس مع الحفاظ على مساحة التنسيق.

يعرض المثال التالي رمز علامة اختيار يحتفظ بمساحته أثناء إخفائه، وبالتالي لا يتحرك النص المجاور له:

Row(modifier, verticalAlignment = Alignment.CenterVertically) {
    Icon(
        painter = painterResource(R.drawable.check),
        contentDescription = "Saved",
        modifier = Modifier
            // The icon keeps its space while it's hidden, so the text doesn't move.
            .visible(isSaved)
    )
    Text("Draft", Modifier.padding(start = 8.dp))
}

استخدِم visible عندما لا يكون من المفترض أن يتحرّك التنسيق حول الدالة المركّبة عند ظهورها واختفائها. لإزالة الدالة المركّبة ومساحتها، لا تستدعِها، أو استخدِم AnimatedVisibility لتحريكها للداخل والخارج.