IllegalArgumentException: maxHeight(473) must be >= minHeight(747) - android

I'm trying out an example from Jetpack Compose and got this error below, I have not changed nothing since this code worked before, the only thing that I have changed was the version from dev15 to alpha-01 and then this happened
java.lang.IllegalArgumentException: maxHeight(473) must be >= minHeight(747)
at androidx.compose.ui.unit.Constraints.copy-msEJaDk(Constraints.kt:158)
at androidx.compose.ui.unit.Constraints.copy-msEJaDk$default(Constraints.kt:146)
at androidx.compose.ui.draw.PainterModifier.modifyConstraints-BRTryo0(PainterModifier.kt:224)
at androidx.compose.ui.draw.PainterModifier.measure-3Jkh9V0(PainterModifier.kt:91)
at androidx.compose.ui.node.ModifiedLayoutNode.performMeasure-BRTryo0(ModifiedLayoutNode.kt:36)
at androidx.compose.ui.node.LayoutNodeWrapper.measure-BRTryo0(LayoutNodeWrapper.kt:120)
at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.performMeasure-BRTryo0(DelegatingLayoutNodeWrapper.kt:106)
at androidx.compose.ui.node.LayerWrapper.performMeasure-BRTryo0(LayerWrapper.kt:70)
at androidx.compose.ui.node.LayoutNodeWrapper.measure-BRTryo0(LayoutNodeWrapper.kt:120)
at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.performMeasure-BRTryo0(DelegatingLayoutNodeWrapper.kt:106)
at androidx.compose.ui.node.LayerWrapper.performMeasure-BRTryo0(LayerWrapper.kt:70)
at androidx.compose.ui.node.LayoutNodeWrapper.measure-BRTryo0(LayoutNodeWrapper.kt:120)
at androidx.compose.foundation.layout.FillModifier.measure-3Jkh9V0(LayoutSize.kt:433)
at androidx.compose.ui.node.ModifiedLayoutNode.performMeasure-BRTryo0(ModifiedLayoutNode.kt:36)
at androidx.compose.ui.node.LayoutNodeWrapper.measure-BRTryo0(LayoutNodeWrapper.kt:120)
at androidx.compose.foundation.layout.SizeModifier.measure-3Jkh9V0(LayoutSize.kt:507)
at androidx.compose.ui.node.ModifiedLayoutNode.performMeasure-BRTryo0(ModifiedLayoutNode.kt:36)
at androidx.compose.ui.node.LayoutNodeWrapper.measure-BRTryo0(LayoutNodeWrapper.kt:120)
at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt:90)
at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:132)
at androidx.compose.ui.platform.AndroidComposeView.observeMeasureModelReads(AndroidComposeView.kt:425)
at androidx.compose.ui.node.OuterMeasurablePlaceable.remeasure-BRTryo0(OuterMeasurablePlaceable.kt:89)
at androidx.compose.ui.node.OuterMeasurablePlaceable.measure-BRTryo0(OuterMeasurablePlaceable.kt:62)
at androidx.compose.ui.node.LayoutNode.measure-BRTryo0(LayoutNode.kt:1095)
at androidx.compose.foundation.layout.RowColumnImplKt$rowColumnMeasureBlocks$1.invoke(RowColumnImpl.kt:90)
at androidx.compose.foundation.layout.RowColumnImplKt$rowColumnMeasureBlocks$1.invoke(RowColumnImpl.kt)
at androidx.compose.ui.LayoutKt$measureBlocksOf$1.measure-2MWCACw(Layout.kt:146)
at androidx.compose.ui.node.InnerPlaceable.performMeasure-BRTryo0(InnerPlaceable.kt:48)
at androidx.compose.ui.node.LayoutNodeWrapper.measure-BRTryo0(LayoutNodeWrapper.kt:120)
at androidx.compose.foundation.layout.PaddingModifier.measure-3Jkh9V0(LayoutPadding.kt:169)
at androidx.compose.ui.node.ModifiedLayoutNode.performMeasure-BRTryo0(ModifiedLayoutNode.kt:36)
at androidx.compose.ui.node.LayoutNodeWrapper.measure-BRTryo0(LayoutNodeWrapper.kt:120)
at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt:90)
at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:132)
at androidx.compose.ui.platform.AndroidComposeView.observeMeasureModelReads(AndroidComposeView.kt:425)
at androidx.compose.ui.node.OuterMeasurablePlaceable.remeasure-BRTryo0(OuterMeasurablePlaceable.kt:89)
at androidx.compose.ui.node.OuterMeasurablePlaceable.measure-BRTryo0(OuterMeasurablePlaceable.kt:62)
at androidx.compose.ui.node.LayoutNode.measure-BRTryo0(LayoutNode.kt:1095)
at androidx.compose.foundation.lazy.LazyForState.measure-mw7JCkE(LazyForState.kt:322)
at androidx.compose.foundation.lazy.
My code is the followin
import android.os.Bundle
import androidx.annotation.DrawableRes
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.Image
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumnFor
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.setContent
import androidx.compose.ui.res.imageResource
import androidx.compose.ui.unit.dp
import androidx.ui.tooling.preview.Preview
import com.example.jetexample.ui.typography
val recipeList = listOf<Recipe>(Recipe(R.drawable.header,"Test", listOf("Azucar","Tomate","lasagna")),
Recipe(R.drawable.header,"Test", listOf("Azucar","Tomate","lasagna")),
Recipe(R.drawable.header,"Test", listOf("Azucar","Tomate","lasagna")))
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
RecipeList(recipeList)
}
}
}
#Composable
fun RecipeCard(recipe: Recipe) {
val image = imageResource(R.drawable.header)
Column(modifier = Modifier.padding(16.dp)) {
val imageModifier = Modifier
.preferredHeightIn(maxHeight = 180.dp)
.fillMaxWidth()
.clip(shape = RoundedCornerShape(8.dp))
Image(image,modifier= imageModifier, contentScale = ContentScale.Crop)
Spacer(Modifier.preferredHeight(16.dp))
Text(recipe.title, style = typography.h6)
for(ingredient in recipe.ingredients){
Text(ingredient,style = typography.body2)
}
}
}
#Composable
fun RecipeList(recipeList:List<Recipe>){
LazyColumnFor(recipeList) { item ->
RecipeCard(recipe = item)
}
}
#Preview(showBackground = true)
#Composable
fun RecipePreview(){
RecipeList(recipeList)
}
data class Recipe(
#DrawableRes val imageResource: Int,
val title: String,
val ingredients: List<String>
)
I think the problem might be in the dp units imported, I really dont know why this happends

Fixed by replacing
.preferredHeightIn(maxHeight = 180.dp)
with
.preferredHeightIn(180.dp)

Related

requestFocus() focuses a TextView, but does not highlight it

I have a Datalogic Memor K – a mobile computer which runs Android 9 and has a hardware keyboard.
In my application, I can move the focus/highlight between controls, including TextView controls with isFocusableInTouchMode = true, manually using the hardware arrow keys (see below).
But when I do it programmatically, requestFocus() returns true, but the TextView does not highlight, although it seems to get the focus, because the next move with the arrow keys starts from it.
I create a project from the Empty activity template.
For better visibility, I add the following to the res/value/themes.xml file:
<!-- Customize your theme here. -->
<item name="android:textSize">25sp</item>
<item name="colorControlHighlight">#color/purple_700</item>
</style>
</resources>
To keep my post shorter, I don't use a layout file and do everything in the code of the main activity:
#file:SuppressLint("SetTextI18n")
package lv.trialto.myapplication
import android.annotation.SuppressLint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val numbers = arrayOf("One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine")
var nextNumberIndex = 0
val rootLinearLayout = LinearLayout(this).apply {
layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)
orientation = LinearLayout.VERTICAL
}
val textViewList = mutableListOf<TextView>()
for (y in 1..3) {
val horizontalLinearLayout = LinearLayout(this).apply {
layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
orientation = LinearLayout.HORIZONTAL
}
rootLinearLayout.addView(horizontalLinearLayout)
for (x in 1..3) {
val cell = TextView(this).apply {
width = (100 * context.resources.displayMetrics.density + 0.5).toInt()
isFocusableInTouchMode = true
text = numbers[nextNumberIndex++]
}
textViewList.add(cell)
horizontalLinearLayout.addView(cell)
}
}
rootLinearLayout.addView(Button(this).apply {
layoutParams = ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
text = "Focus random cell"
setOnClickListener {
val randomTextView = textViewList[textViewList.indices.random()]
val saveText = randomTextView.text
randomTextView.text = "HERE!"
val result = randomTextView.requestFocus()
Toast.makeText(context, "result = $result", Toast.LENGTH_LONG).show()
lifecycleScope.launch {
delay(1000)
randomTextView.text = saveText
}
}
})
setContentView(rootLinearLayout)
}
}
What am I doing wrong?
Also, what is the correct name of this focus/highlight/cursor?

Jetpack Compose - Make LaunchedEffect keep running while app is running in the background

I am developing an android app using Jetpack Compose and have a timer implemented using launchedEffect
here is some dummy code for clearance
LaunchedEffect(key1 = timeLeft) {
if(timeLeft > 0) {
delay(100L)
timeLeft -= 100L
}
}
my problem is that when the app is in the background the LaunchedEffect stops running and the timer is "stuck" on the same value until I return to the app
Launched Effect should not be used for that purpose, but your timer can survive minimization in a coroutine.
var time: Int by remember {
mutableStateOf(0)
}
LaunchedEffect(key1 = true, block = {
CoroutineScope(Dispatchers.IO).launch {
while (isTimerGoing) {
time = time + 1
delay(1000)
}
}
})
Below I'll describe other ways to do it.
You have several options to run a background task.
Alarms
Workmanager
Services
Coroutines
First of all you might not need a background timer. You only need to remember start time and then show the timer when you are drawing ui.
If you need to do something after a period of time, and you know exactly when, use an alarm.
If you need this timer going all the time even with the app closed, consider using a foreground service.
If it is ok to stop the timer when the app is cleared from memory you can use a viewModel.
The best match to your case will be a viewmodel solution.
Here is the sample made from Empty Compose Activity Template:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.lifecycle.viewmodel.compose.viewModel
import ru.makproductions.timerapp.ui.theme.TimerAppTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
TimerAppTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
val viewModel = viewModel(MainViewModel::class.java)
val state = viewModel.state.collectAsState()
LaunchedEffect(key1 = true, block = { viewModel.startTimer() })
Column(modifier = Modifier.fillMaxSize()) {
Text("Timer going: ${state.value.currentTime}")
Button(onClick = {
if (state.value.isTimerGoing) {
viewModel.stopTimer()
} else {
viewModel.startTimer()
}
}) {
if (state.value.isTimerGoing) {
Text(text = "Stop timer")
} else {
Text(text = "Start timer")
}
}
}
}
}
}
}
}
data class MainViewState(
val currentTime: Int = 0,
val isTimerGoing: Boolean = false
)
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.MutableStateFlow
class MainViewModel : ViewModel() {
val state = MutableStateFlow<MainViewState>(MainViewState())
fun startTimer() {
state.tryEmit(state.value.copy(isTimerGoing = true))
CoroutineScope(Dispatchers.IO).launch {
while (state.value.isTimerGoing) {
withContext(Dispatchers.Main) {
state.tryEmit(state.value.copy(currentTime = state.value.currentTime + 1))
}
delay(1000)
}
}
}
fun stopTimer() {
state.tryEmit(state.value.copy(isTimerGoing = false))
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.activity:activity-compose:1.3.1'
implementation "androidx.compose.ui:ui:$compose_ui_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
implementation 'androidx.compose.material:material:1.1.1'
//Add this line to get viewModel(...) in your composable
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1")
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
}
Some docs:
Here is the official guide to background work - https://developer.android.com/guide/background
And here is documentation for the services -
https://developer.android.com/guide/components/services
Try to pass the key which will not change to the LaunchedEffect.

I Have Several Problems In Gson Library in (Jetpack Compose)

Hello Stackoverflow community
I Would like to fetch data from this Rest Api:
https://adeega.xisaabso.online/Api/android_today_dashboard.php
but unfortunately i have several problems in my application
so how can i solved, i am new in jetpack compose
here are my problems:
No value passed for parameter 'Amaahda'
No value passed for parameter 'Expenses'
No value passed for parameter 'Lacagta_La_dirayo'
No value passed for parameter 'Total'
No value passed for parameter 'Amaahda'
None of the following functions can be called with the arguments supplied
build gradle
implementation("com.android.volley:volley:1.2.1")
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
DashBoardItems Class
package com.example.eee.Classes
data class DashBoardItems(
val Amaahda: Float,
val Expenses: Float,
val Lacagta_La_dirayo: Float,
val Total: Float
)
DashBoardScreen.kt
package com.example.eee.Screens
import android.widget.Toast
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import com.example.eee.Cards.DashBoardText
import com.example.eee.Classes.DashBoardItems
import com.google.gson.GsonBuilder
#Composable
fun DashBoard_Screen(navController: NavController){
val context = LocalContext.current
val baseUrl = "https://adeega.xisaabso.online/Api/android_last_vouchers.php"
val dashBoardItems_data = DashBoardItems()
val data = remember {
mutableStateOf<DashBoardItems>(DashBoardItems())
}
val stringRequest = StringRequest(baseUrl, { it ->
val gsonBuilder = GsonBuilder()
val gson = gsonBuilder.create()
gson.fromJson(it, DashBoardItems::class.java)
data.value = dashBoardItems_data
}, {
Toast.makeText(context, it.toString(), Toast.LENGTH_SHORT).show()
}).apply {
DashBoardText(data = data.value)
}
val volleyRequest = Volley.newRequestQueue(context)
volleyRequest.add(stringRequest)
}
DashBoardText Composable
package com.example.eee.Cards
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import com.example.eee.Classes.DashBoardItems
#Composable
fun DashBoardText(data: DashBoardItems){
Text(text = data.Total.toString())
Text(text = data.Amaahda.toString())
}
In those two places, you are calling DashBoardItems constructor without any argument, but it requires 4 of them:
val dashBoardItems_data = DashBoardItems()
val data = remember {
mutableStateOf<DashBoardItems>(DashBoardItems())
}
You can call it like DashBoardItems(0F, 0F, 0F, 0F) or specify default values in your constructor:
data class DashBoardItems(
val Amaahda: Float = 0F,
val Expenses: Float = 0F,
val Lacagta_La_dirayo: Float = 0F,
val Total: Float = 0F,
)
Another problem you will soon encounter is that you can't just call api requests from your composables like that, you will need a LaunchedEffect or better a ViewModel.

Drawable not beign fond in kotlin file

I'm trying to access a drawable resource from a non Activity class, this is because I want to have my composable function in another file rather than having it in the main file, the thing is that from the Main file I can access R.drawable.header , but from the other crated file I cant
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumnFor
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.imageResource
import androidx.compose.ui.unit.dp
import androidx.ui.tooling.preview.Preview
import com.example.jetexample.ui.typography
#Composable
fun RecipeCard(recipe: Recipe){
val image = imageResource(R.drawable.header)
Surface(shape = RoundedCornerShape(8.dp),elevation = 8.dp,modifier = Modifier.padding(8.dp)) {
Column(modifier = Modifier.padding(16.dp)) {
val imageModifier = Modifier.preferredHeight(150.dp).fillMaxWidth().clip(shape = RoundedCornerShape(8.dp))
Image(asset = image,modifier = imageModifier,contentScale = ContentScale.Crop)
Spacer(modifier = Modifier.preferredHeight(16.dp))
Text(text = recipe.title,style = typography.h6)
for(ingredient in recipe.ingredients){
Text(text = ingredient,style = typography.body2)
}
}
}
}
I know it has something to do with the context, thats why I cant access the resource I think, but I have tried with ContextAmbient and I still cant
Check if R.drawable points to the drawable resource folder in your project. As I see you have not imported resources in your file.
import com.example.jetexample.R

App is shutting down unexpectedly - Kotlin

package com.example.firstapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.EditText
import kotlinx.android.synthetic.main.activity_main.*
import kotlin.random.Random
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val deEditText = findViewById<EditText>(R.id.de) as EditText
val ateEditText = findViewById<EditText>(R.id.ate) as EditText
Randomize.setOnClickListener{
val de = Integer.parseInt(deEditText.text.toString())
val ate = Integer.parseInt(ateEditText.text.toString())
RandomDisplay.text = (Random.nextInt(de - ate) + ate).toString()
}
}
}
I'm trying to create an app that gets two values and picks a random integer between them. I don't know what I'm doing wrong, and I really hope someone can help me. Thanks in advance.
val deEditText = findViewById<EditText>(R.id.de) as EditText
val ateEditText = findViewById<EditText>(R.id.ate) as EditText
Random.nextInt(de - ate)
if value from deEditText minus value from ateEditText is zero or negative, Radom.nextInt would throw IllegalArgumentException
// minimize the end bound to 1 by adding max()
RandomDisplay.text = (Random.nextInt(max(1, de - ate)) + ate).toString()

Categories

Resources