Improved pulltorefresh look and implementation

This commit is contained in:
Juha Heinanen
2025-04-18 12:19:05 +03:00
parent 9dcb742631
commit f016d036d8
2 changed files with 87 additions and 113 deletions
@@ -12,7 +12,6 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
@@ -45,9 +44,6 @@ import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults.Indicator
import androidx.compose.material3.pulltorefresh.pullToRefresh
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
@@ -161,36 +157,6 @@ object CustomElements {
} }
} }
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PullToRefreshBox(
isRefreshing: Boolean,
onRefresh: () -> Unit,
modifier: Modifier = Modifier,
contentAlignment: Alignment = Alignment.TopStart,
enabled: Boolean = true,
content: @Composable BoxScope.() -> Unit,
) {
val refreshState = rememberPullToRefreshState()
Box(
modifier.pullToRefresh(
state = refreshState,
isRefreshing = isRefreshing,
onRefresh = onRefresh,
enabled = enabled,
),
contentAlignment = contentAlignment,
) {
content()
Indicator(
modifier = Modifier.align(Alignment.TopCenter),
isRefreshing = isRefreshing,
state = refreshState,
)
}
}
@Composable @Composable
fun DropdownMenu( fun DropdownMenu(
expanded: Boolean, expanded: Boolean,
@@ -99,6 +99,9 @@ import androidx.compose.material3.TextButton
import androidx.compose.material3.TextField import androidx.compose.material3.TextField
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults.Indicator
import androidx.compose.material3.pulltorefresh.pullToRefresh
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
@@ -140,7 +143,6 @@ import com.tutpro.baresip.CustomElements.Checkbox
import com.tutpro.baresip.CustomElements.DropdownMenu import com.tutpro.baresip.CustomElements.DropdownMenu
import com.tutpro.baresip.CustomElements.LabelText import com.tutpro.baresip.CustomElements.LabelText
import com.tutpro.baresip.CustomElements.PasswordDialog import com.tutpro.baresip.CustomElements.PasswordDialog
import com.tutpro.baresip.CustomElements.PullToRefreshBox
import com.tutpro.baresip.CustomElements.SelectableAlertDialog import com.tutpro.baresip.CustomElements.SelectableAlertDialog
import com.tutpro.baresip.CustomElements.Text import com.tutpro.baresip.CustomElements.Text
import com.tutpro.baresip.CustomElements.verticalScrollbar import com.tutpro.baresip.CustomElements.verticalScrollbar
@@ -520,6 +522,10 @@ class MainActivity : ComponentActivity() {
fun MainContent(ctx: Context, contentPadding: PaddingValues) { fun MainContent(ctx: Context, contentPadding: PaddingValues) {
var isRefreshing by remember { mutableStateOf(false) } var isRefreshing by remember { mutableStateOf(false) }
val refreshState = rememberPullToRefreshState()
var offset by remember { mutableFloatStateOf(0f) }
val swipeThreshold = 200
LaunchedEffect(isRefreshing) { LaunchedEffect(isRefreshing) {
if (isRefreshing) { if (isRefreshing) {
delay(1000) delay(1000)
@@ -527,14 +533,13 @@ class MainActivity : ComponentActivity() {
} }
} }
if (showAlert.value) { if (showAlert.value)
AlertDialog( AlertDialog(
showDialog = showAlert, showDialog = showAlert,
title = alertTitle.value, title = alertTitle.value,
message = alertMessage.value, message = alertMessage.value,
positiveButtonText = stringResource(R.string.ok), positiveButtonText = stringResource(R.string.ok),
) )
}
if (showDialog.value) if (showDialog.value)
AlertDialog( AlertDialog(
@@ -547,10 +552,25 @@ class MainActivity : ComponentActivity() {
onNegativeClicked = onNegativeClicked.value onNegativeClicked = onNegativeClicked.value
) )
PullToRefreshBox( SelectableAlertDialog(
openDialog = showSelectItemDialog,
title = getString(R.string.choose_destination_uri),
items = items.value,
onItemClicked = itemAction.value,
neutralButtonText = getString(R.string.cancel),
onNeutralClicked = {}
)
Column(
modifier = Modifier
.imePadding()
.fillMaxWidth()
.padding(contentPadding)
.padding(top = 18.dp, bottom = 6.dp, start = 16.dp, end = 16.dp)
.fillMaxSize()
.pullToRefresh(
state = refreshState,
isRefreshing = isRefreshing, isRefreshing = isRefreshing,
modifier = Modifier.fillMaxSize(),
enabled = pullToRefreshEnabled,
onRefresh = { onRefresh = {
isRefreshing = true isRefreshing = true
if (uas.value.isNotEmpty()) { if (uas.value.isNotEmpty()) {
@@ -560,25 +580,9 @@ class MainActivity : ComponentActivity() {
if (ua.account.regint > 0) if (ua.account.regint > 0)
Api.ua_register(ua.uap) Api.ua_register(ua.uap)
} }
} },
) { enabled = pullToRefreshEnabled,
SelectableAlertDialog(
openDialog = showSelectItemDialog,
title = getString(R.string.choose_destination_uri),
items = items.value,
onItemClicked = itemAction.value,
neutralButtonText = getString(R.string.cancel),
onNeutralClicked = {}
) )
var offset by remember { mutableFloatStateOf(0f) }
val swipeThreshold = 200
Column(
modifier = Modifier
.imePadding()
.fillMaxWidth()
.padding(contentPadding)
.padding(top = 18.dp, bottom = 6.dp, start = 16.dp, end = 16.dp)
.fillMaxSize()
.pointerInput(Unit) { .pointerInput(Unit) {
detectHorizontalDragGestures( detectHorizontalDragGestures(
onDragStart = { offset = 0f }, onDragStart = { offset = 0f },
@@ -627,7 +631,11 @@ class MainActivity : ComponentActivity() {
OnHoldNotice() OnHoldNotice()
AskPasswords(ctx) AskPasswords(ctx)
AskPassword(ctx) AskPassword(ctx)
} Indicator(
modifier = Modifier.align(Alignment.CenterHorizontally),
isRefreshing = isRefreshing,
state = refreshState,
)
} }
} }