I'm sure this is a newbie question, but I'm trying to implement a Material 3 theme. I have added the themes.kt & colors.kt to my com.my.project.ui.theme package. But I don't understand what I can do next to implement these colors as my app is not using these colors and is still using the default material 3 colors that came when I started the app. I'm not finding the disconnect.
I have added the dependencies and removed the old Material dependency
//implementation 'androidx.compose.material:material:1.3.1'
implementation 'androidx.compose.material3:material3:1.1.0-alpha03'
implementation "androidx.compose.material3:material3-window-size-class:1.1.0-alpha03"
implementation "com.google.accompanist:accompanist-flowlayout:0.24.8-beta"
One thing I notice is the function in themes.kt is saying it is never used (grayed out).
#Composable
fun DzoicTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: #Composable () -> Unit) {
val useDynamicColors = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
val colors = when {
useDynamicColors && darkTheme -> dynamicDarkColorScheme(LocalContext.current)
useDynamicColors && !darkTheme -> dynamicLightColorScheme(LocalContext.current)
darkTheme -> DarkColors
else -> LightColors
}
MaterialTheme(
colorScheme = colors,
typography = Typography,
shapes = Shapes,
content = content
)
}
Where does this function get called (DzoicTheme)? Default was AppTheme but instructions said to change it. Is the name important here? Most tutorials show utilizing material 3 colors from the activity compose functions but I do all my design in xml layout files, does this matter? Any help here would be appreciated!
Related
I'm not sure when or what I changed, but all of the sudden the systemUiController has stopped affecting the status bar color in my app. For context, I'm using the accompanist Insets library in combination with system UI controller to get rid of the status and nav bar, and this was working fine until a build or two ago, and now its only working on the nav/gesture bar.
I do this by putting all composables into ProvideWindowInsets, and by setting the bar colors to transparent. For some reason this only works on the nav bar.
To debug, I've stripped my app of everything but the setContent in onCreate of the mainActivity, including all services, and have temporarily removed everything within setContent but an empty theme provider.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
val systemUiController = rememberSystemUiController()
val useDarkIcons = !isSystemInDarkTheme()
SideEffect {
systemUiController.setSystemBarsColor(
color = Color.Transparent,
darkIcons = useDarkIcons
)
}
MicCheckTheme {
ProvideWindowInsets() {
}
}
}
}
When I run this, only the nav bar is transparent. I believe this isn't the fault of the Insets library, as while the status bar retains its color, app content goes underneath the bar, so Insets works as intended.
For further context, I'm using a MainActivity inheriting ComponentActivity with Material3, Compose 1.2.x, and accompanist 0.24.9-beta, although I've tried many different releases in debugging this, none working. I've even created a new test app project and pasted the Insets + SystemUIController sample app from the accompanist github, and even that didn't work.
Please help me! Thanks.
That is because in Material3 compose Theme.kt overrides systemuicontroller changes as follows:
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
(view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb()
ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme
}
}
As a matter of fact, you do not need systemuicontroller libary to update system bars
. You can directly utilise the above code from Theme.kt in Material3 Compose template.
Note: ViewCompat.getWindowInsetsController(view) is now depricated. You should use WindowCompat.getInsetsController(window, view)
My app uses Material 3; however, I'm also using some libraries that use Material 2. The problem is: to get colors with Material 3 you have to use MaterialTheme.colorScheme, but to get them with Material 2 you have to use MaterialTheme.colors. So, the libraries that use Material 2 use MaterialTheme.colors, but when I create my theme I use MaterialTheme.colorScheme:
val DarkColorScheme = darkColorScheme(
primary = Green,
secondary = Blue,
tertiary = Red,
onSurface = Color.White,
error = Red,
)
#Composable
fun StarDictTheme(
darkTheme: Boolean = true,
// Dynamic color is available on Android 12+
dynamicColor: Boolean = true,
content: #Composable () -> Unit
) {
MaterialTheme(
colorScheme = DarkColorScheme,
typography = Typography,
content = content
)
}
So, in the end the libraries don't use my theme colors, and I get dark elements on a dark background.
Is it possible to fix this? Thanks!
I know how to implement BottomSheet in Material 2 Jetpack Compose using BottomSheetScaffold.
But there is no BottomSheetScaffold in Material 3. Also, there is nothing in official samples about BottomSheet.
So I was able to make it work!
It seems that, as of today, BottomSheetScaffold is not available yet on Material3, this is discussed in this issue I found digging around: https://issuetracker.google.com/issues/229839039
I quote the important part from the reply of a google dev:
we aren't in a super easy spot with Swipeable. It currently has a number of critical bugs that need to be addressed first (we are working on this), which is why we are limiting the surface we are exposing for Swipeable in M3 for the time. Our plan for the coming months is to focus on this specific area and improve developer experience.
Material 3 for Jetpack Compose is still in alpha - this means we
consider components production-ready, but the API shape is flexible
while in alpha. This gives us space to iterate while getting
real-world feedback from developers, which ultimately helps improve
your experience. Copy-pasting source code for components that are not
(fully) implemented or exposed in an alpha version can be a good thing
to do in the meantime! Owning the source code while the API shape is
still flexible gives you a number of benefits like ease of updating
dependencies, even if the APIs change, and allows you to evolve your
components in your own pace.
So I just followed the advice and I copy pasted BottomSheetScaffold into my project. Of course it did not work straight away because of a few missing classes and some minor API changes. At the end I was able to make it work by pulling and hacking the following classes and adding them to my project:
BottomSheetScaffold.kt
Drawer.kt
Strings.kt
Swipeable.kt
I have created a gist with the source code if you want to try:
https://gist.github.com/Marlinski/0b043968c2f574d70ee6060aeda54882
You will have to change the import to make it work on your project as well as add the "-Xjvm-default=all" option by adding the following into your gradle file in the android{} section:
android{
...
kotlinOptions {
freeCompilerArgs += ["-Xjvm-default=all"]
// "-Xjvm-default=all" option added because of this error:
// ... Inheritance from an interface with '#JvmDefault' members is only allowed with -Xjvm-default option
// triggered by porting BottomSheetScaffold for Material3 on Swipeable.kt:844
}
}
It works very well for me, will keep this solution until it is officially supported in material3.
Hope it helps!
I got pretty similar results using a fullscreen dialog with AnimatedVisibility, here is the code if interested:
// Visibility state for the dialog which will trigger it only once when called
val transitionState = remember {
MutableTransitionState(false).apply {
targetState = true
}
}
Dialog(
onDismissRequest = {} // You can set a visibility state variable to false in here which will close the dialog when clicked outside its bounds, no reason to when full screen though,
properties = DialogProperties(
// This property makes the dialog full width of the screen
usePlatformDefaultWidth = false
)
) {
// Visibility animation, more information in android docs if needed
AnimatedVisibility(
visibleState = transitionState,
enter = slideInVertically(
initialOffsetY = { it },
animationSpec = ...
),
exit = slideOutVertically(
targetOffsetY = { it },
animationSpec = ...
)
)
) {
Box(
modifier = Modifier.fillMaxSize().background(color = ...)
) {
// Your layout
// This can be any user interraction that closes the dialog
Button(
transitionState.apply { targetState = false }
) ...
}
}
All of this is in a composable function that gets called when a UI action to open said dialog is performed, it's not ideal but it works.
Hope I was able to help!
There is already a great answer by Marlinski, but i would like to add that there is also a ModalBottomSheetLayout which also does not have any implementation for Material 3.
I created a gist for people who need it in use right now:
https://gist.github.com/Pasha831/bdedcfee01acdc96cf3ae643da64f88a
We finally have ModalBottomSheet in Material3.
var openBottomSheet by rememberSaveable { mutableStateOf(false) }
val bottomSheetState = rememberSheetState(skipHalfExpanded = true)
// Sheet content
if (openBottomSheet) {
ModalBottomSheet(
onDismissRequest = { openBottomSheet = false },
sheetState = bottomSheetState,
) {
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center) {
Button(
// Note: If you provide logic outside of onDismissRequest to remove the sheet,
// you must additionally handle intended state cleanup, if any.
onClick = {
scope.launch { bottomSheetState.hide() }.invokeOnCompletion {
if (!bottomSheetState.isVisible) {
openBottomSheet = false
}
}
}
) {
Text("Hide Bottom Sheet")
}
}
}
}
For more link here: https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#ModalBottomSheet(kotlin.Function0,androidx.compose.ui.Modifier,androidx.compose.material3.SheetState,androidx.compose.ui.graphics.Shape,androidx.compose.ui.graphics.Color,androidx.compose.ui.graphics.Color,androidx.compose.ui.unit.Dp,androidx.compose.ui.graphics.Color,kotlin.Function0,kotlin.Function1)
I am having the following issue. I am adding some vector drawable images in my project which is built using Jetpack compose. I am overriding the colors of the drawable by setting
android:fillColor="?colorPrimary"
But, the previous solution, even though it works on a usual Android project, when working on Jetpack compose it is not.
Of course, I have initialized a Material Theme with my colors/typo/shapes.
Any suggetions?
Best regards!
I've run into similar issues where compose doesn't play well with attributes. It prefers to access via colorResource(R.color.colorName).
What you might be looking for is either of the below implementations:
Icon(
Icons.Filled,
"contentDescription",
tint = MaterialTheme.colors.secondary
)
Image(
painter = painterResource(R.drawable.resourceName),
contentDescription = "contentDescription",
colorFilter = ColorFilter.tint(Color.myColor)
)
UPDATE:
I actually found something similar with font attributes. You might want to try something like this:
fun getFontFromAttribute(resId: Int, context: Context): Typeface? =
context.obtainStyledAttributes(R.style.MYSTYLE, intArrayOf(resId))
.use { array ->
val resource = array.getResourceId(array.getIndex(0), 0)
if (resource == 0) {
null
} else {
ResourcesCompat.getFont(context, resource) ?: Typeface.SANS_SERIF
}
}
I am following this YouTube Tutorial where they are using Modifier.preferredSize() on a box and Modifier.preferredHeight() on a Spacer Composable - all other chained Modifiers are fine.
However Android Studio is not recognizing these 2 options.
Here is the code that I am working with:
Column() {
var isBlue by remember { mutableStateOf(false) }
val color = if(isBlue) Color.Blue else Color.Green
Button(onClick = { isBlue = !isBlue }) {}
Spacer(modifier = Modifier.preferredHeight(128.dp))
Box(modifier = Modifier.preferredHeight(128.dp).background(color = color)){}
}
The Editor is high-lighting preferredHeight as unresolved.
This is the image from the IDE for perspective.
I am using compose_version = '1.0.1' and I'm on AS Arctic Fox
preferredSize was renamed to size and preferredHeight to height
If I face some old video/article with invalid api, I'm searching through compose-samples(official samples from the maintainers) commits to find place where this method was deprecated/renamed, it's the easiest way to know if it just was renamed or I need to change more logic. In this case change was on this commit
Modifier.preferredWidth/preferredHeight/preferredSize were renamed to width/height/size starting from 1.0.0-beta01
I resolved it by following the mouse over suggestion, pressing the alt+Enter to import automatically the required referenced packages
I am following the lessons for andoid and kotlin and had stacked with this error.