SideSlider mit reusable MenuItem

This commit is contained in:
2026-01-04 15:08:15 +01:00
parent 5ee5444155
commit 37d8bb064b
3 changed files with 174 additions and 2 deletions

View File

@@ -0,0 +1,61 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="ComposePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewDeviceShouldUseNewSpec" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewParameterProviderOnFirstParameter" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
</profile>
</component>

View File

@@ -18,7 +18,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.itemsIndexed import androidx.compose.foundation.lazy.grid.itemsIndexed
@@ -27,7 +26,10 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Filter
import androidx.compose.material.icons.filled.FilterAlt
import androidx.compose.material.icons.filled.Menu import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.BottomAppBar import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors import androidx.compose.material3.ButtonColors
@@ -38,6 +40,7 @@ import androidx.compose.material3.FabPosition
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.LargeFloatingActionButton import androidx.compose.material3.LargeFloatingActionButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MediumTopAppBar import androidx.compose.material3.MediumTopAppBar
import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
@@ -66,6 +69,8 @@ import com.example.snapandsolve.camera.AlbumViewState
import com.example.snapandsolve.camera.Intent import com.example.snapandsolve.camera.Intent
import com.example.snapandsolve.ui.theme.AppColor import com.example.snapandsolve.ui.theme.AppColor
import com.example.snapandsolve.ui.theme.ButtonColor import com.example.snapandsolve.ui.theme.ButtonColor
import com.example.snapandsolve.ui.theme.SideSlider
import com.example.snapandsolve.ui.theme.SliderMenuItem
import com.example.snapandsolve.ui.theme.WidgetColor import com.example.snapandsolve.ui.theme.WidgetColor
import com.example.snapandsolve.ui.theme.setupLocationDisplay import com.example.snapandsolve.ui.theme.setupLocationDisplay
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -74,6 +79,7 @@ import kotlinx.coroutines.Dispatchers
@Composable @Composable
fun MainScreen(modifier: Modifier = Modifier, application: Application) { fun MainScreen(modifier: Modifier = Modifier, application: Application) {
var showReport by rememberSaveable { mutableStateOf(false) } var showReport by rememberSaveable { mutableStateOf(false) }
var sliderOpen by remember { mutableStateOf(false) }
Scaffold( Scaffold(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
@@ -93,7 +99,8 @@ fun MainScreen(modifier: Modifier = Modifier, application: Application) {
) { ) {
IconButton( IconButton(
onClick = { onClick = {
/*TODO*/ sliderOpen = !sliderOpen
showReport = false
}, },
modifier = Modifier.padding(bottom = 8.dp) modifier = Modifier.padding(bottom = 8.dp)
) { ) {
@@ -110,6 +117,7 @@ fun MainScreen(modifier: Modifier = Modifier, application: Application) {
LargeFloatingActionButton( LargeFloatingActionButton(
onClick = { onClick = {
showReport = true showReport = true
sliderOpen = false
}, },
modifier = Modifier.offset(y = 64.dp), modifier = Modifier.offset(y = 64.dp),
containerColor = ButtonColor containerColor = ButtonColor
@@ -123,6 +131,7 @@ fun MainScreen(modifier: Modifier = Modifier, application: Application) {
modifier = Modifier.padding(innerPadding), modifier = Modifier.padding(innerPadding),
application, application,
showReport = showReport, showReport = showReport,
sliderOpen = sliderOpen,
onDismissReport = { showReport = false }) onDismissReport = { showReport = false })
} }
} }
@@ -132,6 +141,7 @@ fun ContentScreen(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
application: Application, application: Application,
showReport: Boolean, showReport: Boolean,
sliderOpen: Boolean,
onDismissReport: () -> Unit onDismissReport: () -> Unit
) { ) {
val mapViewModel = remember { MapViewModel(application) } val mapViewModel = remember { MapViewModel(application) }
@@ -161,6 +171,23 @@ fun ContentScreen(
viewModel = albumViewModel viewModel = albumViewModel
) )
} }
// RECHTSGRUND: Das Slider
SideSlider(visible = sliderOpen) {
Text(
"Menü",
style = MaterialTheme.typography.titleMedium,
modifier = Modifier.padding(bottom = 12.dp)
)
SliderMenuItem(
text = "Schäden filtern",
icon = Icons.Default.FilterAlt,
onClick = {
/* TODO */
}
)
}
} }
} }

View File

@@ -0,0 +1,84 @@
package com.example.snapandsolve.ui.theme
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.foundation.clickable
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.ui.graphics.vector.ImageVector
@Composable
fun SideSlider(
visible: Boolean,
modifier: Modifier = Modifier,
widthFraction: Float = 0.75f,
animationMillis: Int = 220,
content: @Composable ColumnScope.() -> Unit
) {
Box(modifier = modifier.fillMaxSize()) {
AnimatedVisibility(
visible = visible,
enter = slideInHorizontally(
animationSpec = tween(animationMillis),
initialOffsetX = { -it }
),
exit = slideOutHorizontally(
animationSpec = tween(animationMillis),
targetOffsetX = { -it }
),
modifier = Modifier.align(Alignment.CenterStart)
) {
Column(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth(widthFraction)
.background(WidgetColor)
.padding(16.dp),
content = content
)
}
}
}
@Composable
fun SliderMenuItem(
text: String,
icon: ImageVector,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier
.fillMaxWidth()
.clickable(onClick = onClick)
.padding(horizontal = 12.dp, vertical = 14.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = icon,
contentDescription = text,
tint = MaterialTheme.colorScheme.onSurface
)
Spacer(Modifier.width(16.dp))
Text(
text = text,
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurface
)
}
}