- Change App/Project Name :
- Go to
settings.gradle
and renamerootProject.name
- Go to
strings.xml
and rename@string/app_name
- Change Theme Name in
themes.xml
Gradle Sync
, Clean and rebuild project
- Go to
- Change Package Name :
- Go to
build.gradle
module level, renamenamespace
andapplicationId
- Run gradle
sync
- In the project tab, Tree Appearance > uncheck
Compact Middle Packages
- Right click on package name folder > Refactor > Rename > Do Refactor
- Clean and rebuild project
- Go to
- Reference : Stackoverflow Thread
- Issue: After adding hilt dependencies, it's successfully synced but failed to run and throw error
Execution failed for task ':app:kaptGenerateStubsDebugKotlin'.
> 'compileDebugJavaWithJavac' task (current target is 1.8) and 'kaptGenerateStubsDebugKotlin' task (current target is 17) jvm target compatibility should be set to the same Java version.
Consider using JVM toolchain: https://kotl.in/gradle/jvm/toolchain
-
Solution: Ganti
jvmTarget
dansourceCompatibility
targetCompatibility
ke Java 17 -
Reference: Stackoverflow Thread
- Issue:
The card already set to
fillMaxHeight
but not showing on row.
- Solution:
In the parent add the
.height(IntrinsicSize.Min)
to its modifier
Row(
modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Min)
) {
Child1(
modifier = Modifier
.fillMaxHeight()
.width(100.dp),
) {}
Child2(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
) {...}
}
- Reference: Stackoverflow Thread
- Issue:
In a navigation flow where there are multiple screens (e.g., Screen A > Screen B > Screen C), there may be situations where you want to pop multiple screens off the back stack at once. For example, you might want to navigate directly from Screen C back to Screen A, skipping Screen B. Using the default NavController.popBackStack()
method will only pop one screen at a time, which may not be sufficient for your use case.
- Solution:
A solution to this problem is using the overloaded NavController.popBackStack(route: String, inclusive: Boolean)
method, which pops all destinations up to a specified one.
Here's how you can use this function in your code:
val navController = rememberNavController()
Button(onClick = {
navController.popBackStack(route = "A", inclusive = false)
}) {
Text(text = "Back to Screen A")
}
This code will pop the back stack until it reaches Screen A, but Screen A will remain in the stack, i.e., it will be the current destination after the operation.
If inclusive
is set to false (which is the default), then all destinations up to but not including the one associated with the given route (in this case A) will be popped.
If inclusive
is set to true, then all destinations up to and including the one associated with the given route will be popped.
Remember, popBackStack()
returns a boolean indicating whether it successfully popped the back stack. You should handle the case where it returns false
, which indicates that it could not find a destination associated with the given route
in the back stack.
- Reference: Stackoverflow Thread
- Issue :
In a Jetpack Compose project, a value updated in the ViewModel might not be reflected in a specific composable. Despite the value being changed and observed within the ViewModel, the composable may still show the initial or default value. This can lead to inconsistencies in the UI where the displayed information does not match the actual data state.
- Solution :
A solution to this problem is using the key
function in Jetpack Compose, which can be used to force recomposition of a specific composable based on a particular value. Whenever the value passed to the key
function changes, the composable within the key block will recompose, ensuring that the UI correctly reflects the updated value.
Here's how you can use this approach in your code:
@Composable
fun MyComposable(user: User) {
val score = calculateScore(user)
// This will force recomposition of the inner content whenever the score changes
key(score) {
Text("User score: $score")
// other composables that depend on the score
}
}
By leveraging the key function, developers can ensure that the UI updates in response to specific data changes, resolving the issue where certain composables were not reflecting the updated value when expected. This leads to a more predictable and responsive user experience.
- References : ChatGPT4
- Issue :
In compose dialog the overlay is just black with some opacity, I want to change the color with other color not just black
- Solution :
In DialogProperties set the usePlatformDefaultWidth
to false
, it will make the dialog size is full screen and not limited to platform default width. Wrap your content with Box and set its modifier to fillMaxSize()
and the background()
with the color you wanted.
Dialog(
onDismissRequest = { /*TODO*/ },
properties = DialogProperties(usePlatformDefaultWidth = false)
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(CloveUITheme.colors.primary30.copy(alpha = 0.4f))
) {
YourDialogContent()
}
}
- References : ChatGPT
- Issue :
In compose column there's a content that too large and it needs a vertical scroll. I want to make an animate to bottom of the column and check if it already scrolled to the bottom.
- Solution :
Using scrollState.maxValue
to get the max position of the column and scrollState.value
to get the current position of the column.
Check if already scrolled to the end:
val endReached by remember {
derivedStateOf {
scrollState.value == scrollState.maxValue
}
}
Scroll to the bottom of the column:
coroutineScope.launch {
scrollState.animateScrollTo(scrollState.maxValue)
}
- References : Stackoverflow Thread
- Issue :
In compose app i want to set the specific screen to unable to screen captured by user
- Solution :
Get the activity
in your composable function and set the flags to WindowManager.LayoutParams.FLAG_SECURE
val activity = LocalContext.current as Activity
activity.window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
)
Because compose is a single activity app, you have to clear the flags after the screen changed with DisposableEffect
DisposableEffect(key1 = Unit) {
onDispose {
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
}
}
- References : Youtube video (XML)