اسحب للأسفل لإعادة التحميل.

يتيح مكوّن "السحب لإعادة التحميل" للمستخدمين السحب للأسفل في بداية محتوى التطبيق لإعادة تحميل البيانات.

واجهة برمجة التطبيقات

استخدِم العنصر القابل للتجميع PullToRefreshBox لتنفيذ ميزة "السحب للتحديث" التي تؤدي دور حاوية للمحتوى القابل للتمرير. تتحكم المَعلمات الرئيسية التالية في سلوك التحديث ومظهره:

  • isRefreshing: قيمة منطقية تشير إلى ما إذا كان إجراء إعادة التحميلقيد التقدّم حاليًا.
  • onRefresh: دالة LAMBDA يتم تنفيذها عندما يبدأ المستخدم عملية إعادة تحميل.
  • indicator: تخصيص المؤشر الذي يتم رسمه عند سحب الشاشة لأسفل لإعادة تحميل البيانات

مثال أساسي

يوضّح هذا المقتطف الاستخدام الأساسي PullToRefreshBox:

@Composable
fun PullToRefreshBasicSample(
    items: List<String>,
    isRefreshing: Boolean,
    onRefresh: () -> Unit,
    modifier: Modifier = Modifier
) {
    PullToRefreshBox(
        isRefreshing = isRefreshing,
        onRefresh = onRefresh,
        modifier = modifier
    ) {
        LazyColumn(Modifier.fillMaxSize()) {
            items(items) {
                ListItem({ Text(text = it) })
            }
        }
    }
}

النقاط الرئيسية حول الرمز

  • PullToRefreshBox يلفّ LazyColumn، الذي يعرض قائمة بالسلاسل.
  • تتطلّب PullToRefreshBox مَعلمتَي isRefreshing وonRefresh.
  • يمثّل المحتوى ضمن العنصر PullToRefreshBox المحتوى الذي يمكن التمرير فيه.

النتيجة

يوضّح هذا الفيديو عملية التنفيذ الأساسية لميزة "السحب لإعادة التحميل" من الرمز البرمجي السابق:

الشكل 1. تنفيذ أساسي لميزة "السحب لإعادة التحميل" في قائمة عناصر

مثال متقدّم: تخصيص لون المؤشر

@Composable
fun PullToRefreshCustomStyleSample(
    items: List<String>,
    isRefreshing: Boolean,
    onRefresh: () -> Unit,
    modifier: Modifier = Modifier
) {
    val state = rememberPullToRefreshState()

    PullToRefreshBox(
        isRefreshing = isRefreshing,
        onRefresh = onRefresh,
        modifier = modifier,
        state = state,
        indicator = {
            Indicator(
                modifier = Modifier.align(Alignment.TopCenter),
                isRefreshing = isRefreshing,
                containerColor = MaterialTheme.colorScheme.primaryContainer,
                color = MaterialTheme.colorScheme.onPrimaryContainer,
                state = state
            )
        },
    ) {
        LazyColumn(Modifier.fillMaxSize()) {
            items(items) {
                ListItem({ Text(text = it) })
            }
        }
    }
}

النقاط الرئيسية حول الرمز

  • يتم تخصيص لون المؤشر من خلال السمتَين containerColor وcolor في المَعلمة indicator.
  • يدير rememberPullToRefreshState() حالة إجراء إعادة التحميل. يمكنك استخدام هذه الحالة مع المَعلمة indicator.

النتيجة

يعرض هذا الفيديو عملية تنفيذ ميزة "السحب لإعادة التحميل" باستخدام مؤشر ملوّن:

الشكل 2. تنفيذ ميزة "السحب لإعادة التحميل" باستخدام نمط مخصّص

مثال متقدّم: إنشاء مؤشر مخصّص بالكامل

يمكنك إنشاء مؤشرات مخصّصة معقّدة من خلال الاستفادة من العناصر القابلة للتجميع والمؤثرات المتحركة الحالية.توضّح هذه المقتطف كيفية إنشاء مؤشر مخصّص بالكامل في عملية تنفيذ ميزة "السحب للتحديث":

@Composable
fun PullToRefreshCustomIndicatorSample(
    items: List<String>,
    isRefreshing: Boolean,
    onRefresh: () -> Unit,
    modifier: Modifier = Modifier
) {
    val state = rememberPullToRefreshState()

    PullToRefreshBox(
        isRefreshing = isRefreshing,
        onRefresh = onRefresh,
        modifier = modifier,
        state = state,
        indicator = {
            MyCustomIndicator(
                state = state,
                isRefreshing = isRefreshing,
                modifier = Modifier.align(Alignment.TopCenter)
            )
        }
    ) {
        LazyColumn(Modifier.fillMaxSize()) {
            items(items) {
                ListItem({ Text(text = it) })
            }
        }
    }
}

// ...
@Composable
fun MyCustomIndicator(
    state: PullToRefreshState,
    isRefreshing: Boolean,
    modifier: Modifier = Modifier,
) {
    Box(
        modifier = modifier.pullToRefreshIndicator(
            state = state,
            isRefreshing = isRefreshing,
            containerColor = PullToRefreshDefaults.containerColor,
            threshold = PositionalThreshold
        ),
        contentAlignment = Alignment.Center
    ) {
        Crossfade(
            targetState = isRefreshing,
            animationSpec = tween(durationMillis = CROSSFADE_DURATION_MILLIS),
            modifier = Modifier.align(Alignment.Center)
        ) { refreshing ->
            if (refreshing) {
                CircularProgressIndicator(Modifier.size(SPINNER_SIZE))
            } else {
                val distanceFraction = { state.distanceFraction.coerceIn(0f, 1f) }
                Icon(
                    imageVector = Icons.Filled.CloudDownload,
                    contentDescription = "Refresh",
                    modifier = Modifier
                        .size(18.dp)
                        .graphicsLayer {
                            val progress = distanceFraction()
                            this.alpha = progress
                            this.scaleX = progress
                            this.scaleY = progress
                        }
                )
            }
        }
    }
}

النقاط الرئيسية حول الرمز

  • استخدم المقتطف السابق Indicator المقدَّم من المكتبة. ينشئ هذا المقتطف مؤشرًا مخصّصًا قابلاً للتجميع يُسمى MyCustomIndicator. في هذه السلسلة المكوّنة، يعالج المُعدِّل pullToRefreshIndicator موضع العنصر ويشغّل مجددًا عملية إعادة التحميل.
  • كما هو الحال في المقتطف السابق، تم استخراج مثيل PullToRefreshState، وبالتالي يمكن تمرير المثيل نفسه إلى كل من PullToRefreshBox وpullToRefreshModifier.
  • يتم استخدام لون الحاوية وحدّ الموضع من فئة PullToRefreshDefaults. بهذه الطريقة، يمكنك إعادة استخدام السلوك التلقائي والنمط من مكتبة Material، مع تخصيص العناصر التي تهمّك فقط.
  • يستخدم MyCustomIndicator Crossfade للانتقال بين رمز السحابة ورمز CircularProgressIndicator. يتم تكبير رمز السحابة عندما يسحب المستخدم، ويتحول إلى CircularProgressIndicator عند بدء إجراء التحديث.
    • يستخدم targetState isRefreshing لتحديد الحالة التي سيتم عرضها (targetStateرمز السحابة أو مؤشر التقدم الدائري).
    • animationSpec تحدّد صورة متحركة tween لعملية النقل، مع مدة محدّدة تبلغ CROSSFADE_DURATION_MILLIS.
    • يمثّل state.distanceFraction المسافة التي سحب فيها المستخدم للأسفل، ويتراوح من 0f (بدون سحب) إلى 1f (سحب كامل).
    • يُعدّ المُعدِّل graphicsLayer مُعدِّلاً للحجم والشفافية.

النتيجة

يعرض هذا الفيديو المؤشر المخصّص من الرمز البرمجي السابق:

الشكل 3. تنفيذ ميزة "السحب لإعادة التحميل" باستخدام مؤشر مخصّص

مصادر إضافية