צריך למשוך כדי לרענן

הרכיב "למשוך למטה לרענון" מאפשר למשתמשים לגרור את המסך כלפי מטה בתחילת התוכן של האפליקציה כדי לרענן את הנתונים.

פלטפורמת ה-API

משתמשים ברכיב ה-Composable‏ 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.pullToRefresh(
            state = state,
            isRefreshing = isRefreshing,
            threshold = PositionalThreshold,
            onRefresh = {

            }
        ),
        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. בפונקציה הקומפוזבילית הזו, ה-modifier pullToRefreshIndicator מטפל במיקום ובהפעלת הרענון.
  • כמו בקטע הקוד, בדוגמה הזו מחלצים את המכונה PullToRefreshState, כדי שתוכלו להעביר את אותה מכונה גם ל-PullToRefreshBox וגם ל-pullToRefreshModifier.
  • בדוגמה נעשה שימוש בצבע של הקונטיינר ובסף המיקום מהמחלקה PullToRefreshDefaults. כך אפשר להשתמש שוב בפעולת ברירת המחדל ובסגנון מספריית Material, ולהתאים אישית רק את הרכיבים שמעניינים אתכם.
  • ‫MyCustomIndicator משתמש ב-Crossfade כדי לעבור בין סמל ענן לבין CircularProgressIndicator. סמל הענן גדל כשהמשתמש מושך, ומשתנה לCircularProgressIndicator כשפעולת הרענון מתחילה.
    • הפונקציה targetState משתמשת ב-isRefreshing כדי לקבוע איזה מצב להציג (סמל הענן או אינדיקטור ההתקדמות המעגלי).
    • animationSpec מגדיר אנימציה של tween למעבר, עם משך זמן מוגדר של CROSSFADE_DURATION_MILLIS.
    • ‫state.distanceFraction מייצג את המרחק שהמשתמש משך למטה, בטווח שבין 0f (ללא משיכה) ל-1f (משיכה מלאה).
    • המשתנה graphicsLayer משנה את קנה המידה והשקיפות.

תוצאה

בסרטון הזה מוצג האינדיקטור בהתאמה אישית מהקוד הקודם:

איור 3. הטמעה של משיכה למטה לרענון עם אינדיקטור מותאם אישית.

מקורות מידע נוספים