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

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

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

התוצאה

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

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

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