Showing posts with label Swipe to refresh. Show all posts
Showing posts with label Swipe to refresh. Show all posts

Tuesday, January 4, 2022

Swipe to refresh

Swipe to refresh manually refreshes screen content with a user action or gesture.

package compose.material.theme

import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.LinearProgressIndicator
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.google.accompanist.swiperefresh.SwipeRefresh
import com.google.accompanist.swiperefresh.SwipeRefreshState
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
import compose.material.theme.ui.theme.Purple40
import compose.material.theme.ui.theme.Purple80
import kotlinx.coroutines.delay


@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SwipeToRefreshDemo(navController: NavController) {
    val context = LocalContext.current
    var isRefreshing by remember { mutableStateOf(false) }
    val swipeRefreshState = rememberSwipeRefreshState(isRefreshing)


    Scaffold(
        topBar = {
            CenterAlignedTopAppBar(
                title = { Text("Swipe to refresh") },
                Modifier.background(Purple40),
                navigationIcon = {
                    IconButton(onClick = { /* doSomething() */
                        navController.navigateUp()
                    }) {
                        Icon(
                            imageVector = Icons.Filled.ArrowBack,
                            contentDescription = "Localized description"
                        )
                    }
                },
            )
        },
        content = {

            Column {
                SwipeRefresh(
                    state = swipeRefreshState,
                    onRefresh = {
                        isRefreshing = true
                    },
                    indicator = { state, trigger ->
                        CustomViewPullRefreshView(state, trigger)
                    }
                ) {


                    // body content
                    val scrollState = rememberScrollState()
                    BlogContentSimple(scrollState)

                    // 2 sec delay
                    LaunchedEffect(isRefreshing) {
                        if (isRefreshing) {
                            delay(2000L)
                            isRefreshing = false
                        }
                    }
                }
            }


        }
    )

}

@Composable
fun CustomViewPullRefreshView(
    swipeRefreshState: SwipeRefreshState,
    refreshTriggerDistance: Dp,
    color: Color = Purple80
) {
    Box(
        Modifier
            .drawWithCache {
                onDrawBehind {
                    val distance = refreshTriggerDistance.toPx()
                    val progress = (swipeRefreshState.indicatorOffset / distance).coerceIn(0f, 1f)
                    val brush = Brush.verticalGradient(
                        0f to color.copy(alpha = 0.45f),
                        1f to color.copy(alpha = 0f)
                    )
                    drawRect(
                        brush = brush,
                        alpha = FastOutSlowInEasing.transform(progress)
                    )
                }
            }
            .fillMaxWidth()
            .height(80.dp)
    ) {
        if (swipeRefreshState.isRefreshing) {
            LinearProgressIndicator(
                Modifier.fillMaxWidth(),
                color = Purple80
            )
        } else {
            val trigger = with(LocalDensity.current) { refreshTriggerDistance.toPx() }
            val progress = (swipeRefreshState.indicatorOffset / trigger).coerceIn(0f, 1f)
            LinearProgressIndicator(
                progress = progress,
                modifier = Modifier.fillMaxWidth(),
                color = Purple40
            )
        }
    }
}



Accompanist SwipeRefresh library 
Utilities for Jetpack Compose : 
   implementation "com.google.accompanist:accompanist-swiperefresh:0.22.0-rc"

..