kotlin.NotImplementedError: An operation is not implemented: not implemented AlertDialog - kotlin

I was trying to practice a little with desktop compose for kotlin and when i was trying to implement AlertDialog element I got this exception:
Exception in thread "AWT-EventQueue-0 #coroutine#3" kotlin.NotImplementedError: An operation is not implemented: not implemented
The code that im trying to run :
fun main() {
var text = mutableStateOf(0F)
var num = mutableStateOf("a")
Window(
size = IntSize(500, 500),
title = num.value,
menuBar = MenuBar(
Menu(
name = "Test",
MenuItem(
name = "Dodaj random",
onClick = {
text.value = text.value + Random.nextFloat()
if (text.value > 1F) {
text.value = 0F
num.value += "a"
}
},
shortcut = KeyStroke(Key.A)
),
MenuItem(
name = "Exit",
onClick = {
AppManager.exit()
},
shortcut = KeyStroke(Key.L)
)
)
)
) {
MaterialTheme {
Column(Modifier.fillMaxSize(), Arrangement.spacedBy(12.dp)) {
LinearProgressIndicator(text.value.toFloat(), modifier = Modifier.align(Alignment.CenterHorizontally))
val openDialog = remember { mutableStateOf(false) }
Button(
onClick = {
openDialog.value = true
}) {
Text("Click me!")
}
if (openDialog.value) {
AlertDialog(
onDismissRequest = { openDialog.value = false },
title = { Text("Dialog title") },
text = { Text("Here is a text") },
confirmButton = {
Button(
onClick = {
openDialog.value = false
}
) { Text("Confirm butt") }
},
dismissButton = {
Button(
onClick = {
openDialog.value = false
}
) { Text("Diss butt") }
}
)
}
Button(
onClick = {
text.value += 0.1F
if (text.value > 1F) {
text.value = 0F
num.value += "a"
}
},
modifier = Modifier.align(Alignment.CenterHorizontally)
) {
Text(text.value.toString())
}
Button(
onClick = {
num.value += "a"
},
modifier = Modifier.align(Alignment.CenterHorizontally)
) {
Text(num.component1())
}
}
}
}
}
Only when I'm trying to click on the "Click me" button I'm getting this exception other buttons works perfectly.
My imports
import androidx.compose.desktop.AppManager
import androidx.compose.desktop.Window
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.LinearProgressIndicator
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.KeyStroke
import androidx.compose.ui.window.Menu
import androidx.compose.ui.window.MenuBar
import androidx.compose.ui.window.MenuItem
import kotlin.random.Random

Your issue seems related to this github issue.
To solve it simply update compose dependency to 0.2.0-build132.
Complete example of my build.gradle with the correct versions:
import org.jetbrains.compose.compose
plugins {
kotlin("jvm") version "1.4.20"
id("org.jetbrains.compose") version "0.2.0-build132"
}
repositories {
jcenter()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
dependencies {
implementation(compose.desktop.currentOs)
}
compose.desktop {
application {
mainClass = "MainKt"
}
}

Related

Problem with custom dialog show in jetpack compose. Not correct background

I'm created custom dialog from common class in ini
init {
activity.setContent {
CustomDialog(viewModel)
}
}
#Composable
fun CustomDialog(viewModel: ViewModel){
Dialog(
onDismissRequest = { },
properties = DialogProperties(dismissOnBackPress = true, dismissOnClickOutside = true)
) {
}
}
But under dialog background is an empty activity, but must be a preference activity.
Not correct composable:
correct dialog via XML:
I tried, but didn't help
Surface(modifier = Modifier.background(Color.Transparent)) {
CustomDialog(viewModel)
}
```
Exampe:
Dialog(onDismissRequest = { onDismissRequest() }, properties = DialogProperties()) {
Column(
modifier = Modifier
.wrapContentSize()
.background(
color = MaterialTheme.colors.surface,
shape = RoundedCornerShape(size = 16.dp)
).clip(shape = RoundedCornerShape(size = 16.dp))
) {
//.....
}
}
Found solution:
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog?.window?.setDimAmount(0.0f)

Jetpack Compose: TextField aligns outside of AlertDialog as text grows

If you run the following composable and enter a long multiline text into the textfield, you will see that as the text grows, the textfield leaves the AlertDialog.
Is there a way to fix this?
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
#Preview
#Composable
fun MyComposable() {
var text by remember {
mutableStateOf("Press enter a couple of times to see the problem")
}
AlertDialog(
onDismissRequest = { },
title = {
OutlinedTextField(
value = text,
onValueChange = { text = it },
textStyle = MaterialTheme.typography.h5,
label = { Text(text = "Text") },
modifier = Modifier
.fillMaxWidth()
.height(150.dp)
)
},
confirmButton = {
TextButton(
onClick = {}
) {
Text("Done")
}
},
dismissButton = {
TextButton(
onClick = { }
) {
Text("Cancel")
}
}
)
}
Modifier.heightIn constrain the height of the content to be between mindp and maxdp as permitted by the incoming measurement Constraints. If the incoming constraints are more restrictive the requested size will obey the incoming constraints and attempt to be as close as possible to the preferred size.
Column {
var text by remember { mutableStateOf("some text")}
OutlinedTextField(value = text,
onValueChange = {text = it},
textStyle = MaterialTheme.typography.headlineSmall,
label = { Text(text = "Text") },
modifier = Modifier.fillMaxWidth()
.heightIn(min = 0.dp, max = 150.dp))
}
Textfield will grow to max height specified in heightIn modifier and then start scrolling.

Jetpack Compose imitates Twitter user homepage

Because scrolling nesting cannot be used, I used the following method to achieve the scrolling nesting effect.
However, the effect is not ideal, and the scroll position of the list cannot be handled well when switching between pages.
Is my way the best solution? Is there a better solution to this problem?
Or how can this solution of mine solve the problem of alignment of the scroll position of the list?
YouTube Video
package com.feifeng.my
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.feifeng.app.theme.FlywindTheme
import com.google.accompanist.pager.*
import kotlinx.coroutines.launch
import kotlin.math.roundToInt
#ExperimentalPagerApi
#ExperimentalMaterial3Api
#Composable
fun UserView() {
Scaffold(
topBar = {
SmallTopAppBar(title = {
Text(text = "User Home")
})
},
content = {
UserContent()
}
)
}
#ExperimentalPagerApi
#Composable
fun UserContent() {
val userGridState = rememberLazyGridState()
val likeGridState = rememberLazyGridState()
val favoriteGridState = rememberLazyGridState()
val headerOffsetY = rememberSaveable { mutableStateOf(0f) }
val headerHeight = rememberSaveable { mutableStateOf(0) }
val pagerState = rememberPagerState()
Box(modifier = Modifier.fillMaxSize()) {
HorizontalPager(count = 3, state = pagerState, itemSpacing = 16.dp) { page ->
if (page == 0) {
UserContentColumn(30, userGridState, headerHeight.value) {
headerOffsetY.value = it
}
}
if (page == 1) {
UserContentColumn(10, likeGridState, headerHeight.value) {
headerOffsetY.value = it
}
}
if (page == 2) {
UserContentColumn(3, favoriteGridState, headerHeight.value) {
headerOffsetY.value = it
}
}
}
Column(modifier = Modifier
.offset {
IntOffset(x = 0, y = headerOffsetY.value.roundToInt())
}
.background(Color.White)
.onSizeChanged { headerHeight.value = it.height }) {
Row(modifier = Modifier.padding(16.dp)) {
Icon(imageVector = Icons.Filled.Person,
contentDescription = "user",
tint = Color.Gray,
modifier = Modifier.size(80.dp))
Text(text = "User Name", modifier = Modifier.padding(16.dp), fontSize = 24.sp)
}
Text(text = "User Bio", modifier = Modifier.padding(16.dp))
UserTabBar(titleList = listOf("Video", "Like", "Favorite"), pagerState = pagerState)
}
}
}
#Composable
fun UserContentColumn(count: Int, state: LazyGridState, headerHeight: Int, onScroll: (Float) -> Unit) {
val offsetY = rememberSaveable { mutableStateOf(0f) }
val scrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
offsetY.value = offsetY.value + available.y
if (offsetY.value > 0) {
offsetY.value = 0f
}
onScroll(offsetY.value)
return Offset.Zero
}
}
}
val current = LocalDensity.current
LazyVerticalGrid(state = state,
columns = GridCells.Fixed(2),
horizontalArrangement = Arrangement.spacedBy(3.dp),
verticalArrangement = Arrangement.spacedBy(3.dp),
contentPadding = PaddingValues(top = current.run { headerHeight.toDp() } + 3.dp, start = 3.dp, end = 3.dp),
modifier = Modifier.nestedScroll(scrollConnection)) {
items(count = count) {
Text(text = "Grid Item",
modifier = Modifier
.fillMaxWidth()
.height(100.dp)
.background(Color.Yellow)
.padding(32.dp))
}
}
}
#ExperimentalPagerApi
#Composable
fun UserTabBar(titleList: List<String>, pagerState: PagerState) {
val scope = rememberCoroutineScope()
androidx.compose.material.TabRow(
selectedTabIndex = pagerState.currentPage,
indicator = { tabPositions ->
TabRowDefaults.Indicator(
Modifier.pagerTabIndicatorOffset(pagerState, tabPositions)
)
},
backgroundColor = Color.White,
contentColor = MaterialTheme.colorScheme.primary) {
titleList.forEachIndexed { index, title ->
Tab(
text = { Text(text = title) },
selected = pagerState.currentPage == index,
onClick = {
scope.launch {
pagerState.scrollToPage(index)
}
}
)
}
}
}
#ExperimentalPagerApi
#ExperimentalMaterial3Api
#Preview
#Composable
fun PreviewTest() {
UserView()
}

Make `TextField` look active without it having a default value

I was wondering how I would go about making a TextField always look active:
Without it actually having a default value like the TextField in the screenshot does
My current code for the TextField in the screenshot is:
TextField(
value = npcId.toString(),
onValueChange = { npcId = it.toInt() },
label = { Text("Npc id") },
enabled = true
)
So essentially you do not want the default value to display in the TextField.
If the default value is -1 in this case, the following should work:
TextField(
value = if (npcID == -1) "" else npcId.toString(),
onValueChange = { npcId = it.toInt() },
label = { Text("Npc id") },
enabled = true
)
I succeded with this way.It is here source code:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.platform.LocalTextInputService
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import kotlinx.coroutines.delay
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MainScreen()
}
}
}
#Composable
fun MainScreen() {
Surface(
modifier = Modifier.fillMaxSize()
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
AutoFocusingText()
}
}
}
#Composable
fun AutoFocusingText() {
val focusRequester = remember { FocusRequester() }
val inputService = LocalTextInputService.current
val focus = remember { mutableStateOf(true) }
val text = remember { mutableStateOf("-1")}
TextField(
value = if (text.value == "-1") "" else text.value,
onValueChange = {
text.value = it
},
label = { Text("Npc id") },
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
modifier = Modifier
.focusRequester(focusRequester)
.onFocusChanged {
if (focus.value != it.isFocused) {
focus.value = it.isFocused
if (!it.isFocused) {
inputService?.hideSoftwareKeyboard()
}
}
}
)
LaunchedEffect(true) {
delay(100)
inputService?.showSoftwareKeyboard()
focusRequester.requestFocus()
}
}
#ExperimentalComposeUiApi
#Preview(showBackground = true)
#Composable
fun DefaultPreview() {
MainScreen()
}

Jetpack compose: scrolling in dialog gives strange effects

I'm trying to create a dialog where you can pick a number. I use FlowRow from Accompanist. But it gives strange results when scrolling. I guess that I'm missing something here.
The code:
#Composable
fun AlertDialogErrorTest() {
var showDlg by remember { mutableStateOf(false)}
val scrollState = rememberScrollState()
if (showDlg) {
AlertDialog(
onDismissRequest = { showDlg = false },
title = { Text(text = "Pick something from the list") },
text = {
FlowRow(modifier = Modifier.verticalScroll(scrollState)) {
for (i in 1..100) {
Box (modifier = Modifier.size(48.dp).padding(8.dp).background(Color.LightGray), contentAlignment = Alignment.Center) {
Text (i.toString())
}
}
}
},
confirmButton = {
TextButton(onClick = { showDlg = false }) {
Text("Done")
}
},
dismissButton = {
TextButton(onClick = { showDlg = false }) {
Text("Cancel")
}
}
)
}
Button(onClick = {showDlg = true}) {
Text("Show dialog")
}
}
The result when scrolling:
This is because AlertDialog does not currently support scrollable content. If you think this is a bug, you can report it in the Compose issue tracker.
Meanwhile, you can use a plain Dialog, which lays under the AlertDialog.
Dialog(
onDismissRequest = { showDlg = false },
content = {
Column(Modifier.background(Color.White)) {
Text(
text = "Pick something from the list",
style = MaterialTheme.typography.subtitle1,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
FlowRow(
modifier = Modifier
.verticalScroll(scrollState)
.weight(1f)
) {
for (i in 1..100) {
Box(
modifier = Modifier
.size(48.dp)
.padding(8.dp)
.background(Color.LightGray),
contentAlignment = Alignment.Center
) {
Text(i.toString())
}
}
}
FlowRow(
mainAxisSpacing = 8.dp,
crossAxisSpacing = 12.dp,
modifier = Modifier
.align(Alignment.End)
.padding(horizontal = 8.dp, vertical = 2.dp)
) {
TextButton(onClick = { showDlg = false }) {
Text("Cancel")
}
TextButton(onClick = { showDlg = false }) {
Text("Done")
}
}
}
},
)
Result:
I have faced the same issue, and the work around is to pass null in both title , and text, and to put the whole content in the buttons, you might check the below example, and please forgive my naming :).
AlertDialog(
onDismissRequest = {
state.onDismiss(state.data)
},
title = null,
text = null,
buttons = {
Column {
val expandedState =
state.data.expandedState
expandedState?.let {
RenderFieldPerCorrespondingState(it.title)
LazyColumnViewGroupComposable(
viewGroupState = it.itemsState,
scrollTo = scrollTo
)
ViewGroupComposable(viewGroupState = it.actionsState)
}
}
}
)