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

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

פלטפורמת ה-API

אפשר להשתמש ב-PullToRefreshBox composable כדי להטמיע משיכה לרענון, שפועל כקונטיינר לתוכן שאפשר לגלול בו. הפרמטרים העיקריים הבאים קובעים את התנהגות הרענון ואת המראה:

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

תוצאה

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

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

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