How to do scrollable clickable text in Glance widget? - android-jetpack-compose

I want to do the following:
Column(modifier = modifier.verticalScroll().clickable(
onClick = actionStartActivity(MainActivity::class.java)
)) {
Text(text = "some really long text")
}
The problem is that there is no verticalScroll modifier, so the only way I can figure out how to get the content to scroll is by using a LazyColumn, however if I try to add a clickable modifier to the LazyColumn then the widget won't load. If I wrap the LazyColumn in a Column I can then add the clickable modifier to the Column, but then clicking anywhere on the text only briefly highlights the text, it doesn't perform the clickable action.
Is there a way to accomplish this currently in Glance?

Looks like if I put a clickable modifier on every item inside of the LazyColumn then it pretty much accomplishes what I'm trying to do. It would be nice if I could just put a clickable modifier on the whole LazyColumn instead though or at least be able to put it on a wrapping Column. It would also be nice if I could just use a Column instead of needing to use a LazyColumn just to get it to be scrollable.

Related

Jetpack Compose BottomSheetScaffold: Smooth closing

I'm using Jetpack Compose with the BottomSheetScaffold. To be able to show and hide the bottom sheet from both within and outside the composable, I used a showBottomSheet: MutableState<Boolean> variable. The peek height within the composable is then determined like this:
val baseBottomSheetPeekHeight by remember { mutableStateOf(60.dp) }
val bottomSheetPeekHeight = if (showBottomSheet.value) baseBottomSheetPeekHeight else 0.dp
Later, in the BottomSheetScaffold, I use the variable like this:
BottomSheetScaffold(
...
sheetPeekHeight = bottomSheetPeekHeight,
...
)
(Full reproducer project here: https://github.com/dbrgn/compose-repro)
This generally works as intended, I can set showBottomSheet.value to false to hide the bottom sheet. However, the hiding looks janky, because not all sub-composables are hidden at the same time.
It's a bit hard to see in the animation above due to the GIF conversion, but when closing the bottom sheet peek pane, the other content (below it) is visible for a short moment, before the bottom sheet disappears.
Is there a way to avoid this janky hiding behavior? Or even better, is there a way to smoothly animate the hiding of the pane?
In my case for Smooth closing BottomSheetScaffold I used to: scaffoldState.bottomSheetState.animateTo(Collapsed, tween(duration))
-- (when duration is any Int you want).
The same for Expanding:
scaffoldState.bottomSheetState.animateTo(Expanded, tween(duration))
If you look at the source code of collapse() or expand() function, you will see there just calling animateTo(Expanded) and animateTo(Collapsed). You can customize animateTo() as you wish.
See animateTo() documentation.

How to keep the components in the same place in FormLayout for Vaadin Flow

I would like to use FormLayout where one of the fields is visible depending on another field. Is there a way to keep the formatting the same, that is for all the fields after it to stay in their same position when another component is invisible.
Below is the code to reproduce as well as a screenshots of what I would like compared to the current behavior. In essence each time you select the combobox you make the "Year Joined Team" field invisible/visible.
TextField nameTextField = new TextField("Name");
ComboBox<String> teamComboBox = new ComboBox<>("Team");
DatePicker yearJoinedDatePicker = new DatePicker("Year Joined Team");
TextField moreFieldsTextFields = new TextField("More fields");
FormLayout formLayout = new FormLayout();
formLayout.setWidth("600px");
formLayout.setResponsiveSteps(new FormLayout.ResponsiveStep("0", 2, FormLayout.ResponsiveStep.LabelsPosition.TOP));
formLayout.add(nameTextField,
teamComboBox, yearJoinedDatePicker,
moreFieldsTextFields);
teamComboBox.setItems(List.of("One", "Two"));
teamComboBox.addValueChangeListener(change -> yearJoinedDatePicker.setVisible(!yearJoinedDatePicker.isVisible()));
formLayout.setColspan(nameTextField, 2);
add(formLayout);
Ideally the goal is to have the fields below the yearJoinedTeamDatePicker component to stay below so that all other components below continue to be aligned correctly when it's set to be invisible.
Instead what actually happens is that all the components are shifted on field to the left, as if the invisible component is no longer part of the FormLayout. Meaning the moreFieldsTextField is now on a different row, and if everything is setup for two columns every row will be incorrect. I understand that this makes sense in some context but in a FormLayout is there a way to keep the form formatted if a component is invisible?
If for example I had firstname and lastname as two side by side fields they would now be on different rows as shown below:
A very hacky solution would be to add in a Span component or something like that and make it invisible when the yearJoinedDatePicker field is visible, and invisible when it's visible. Basically fill it in with an empty field when it's invisible. That is a hacky workaround but it doesn't seem like an appropriate solution. With that in mind is there a way to keep the formatting/layout if a component is invisible?
What you are trying to achieve is sort of defying the purpose of FormLayout. FormLayout has css flex rules to wrap elements / components by row. Thus if you switch visibility of a component, the behavior is as you described.
One thing you could do, is to wrap "Team" and "Year joined team" inside e.g. HorizontalLayout and set
formLayout.setColspan(horizontalLayout, 2);
See, also my previous answer about FormLayout https://stackoverflow.com/a/69270190/8962195
If you want to keep the place, maybe it's vable for you to set the field ti disabled with setEnabled.
I'm not sure how it would behave, but you could try CSS display: none instead of the setVisibility(false).

Vaadin 14: tooltip at Textfield label with icon, text and image

There's this Vaadin 14 TextField created with field = new TextField(...); field.setLabel("Phone number"); like this:
I'd like to add an interactive info icon into that label like this:
When a user clicks (or touches) at the info icon then the system should show a popup or dialogue with some additional information (formated text and images).
I tried to add some HTML and JavaScript like this: field.setLabel("Phone number <span onclick='...'>?</span>"); but the browser just shows exactly that technical String with all its tags and so on.
I already set tooltips with field.getElement().setAttribute("title", "Some information"); but without formatting this is not fancy for longer text and as far as I know not usable for images.
field.setHelperText(...) also is not what I'm looking for because it shows the text durably and not just at a click/touch.
Is there a Vaadin way to achieve that interactive info icon? Otherwise I would to try it with JavaScript and CSS (querying the label element and adding hidden children to the TextField and show them when hovering the label like in this example https://www.scriptol.com/css/tooltip.php ).
Source of the question mark: vaadin:info-circle-o (https://vaadin.com/components/vaadin-icons/html-examples)
The "problem" with the label on fields as of 14.6 is, that it is just an
property on the element and while it ends up as the content of
a <label> tag, you can not provide anything but text.
One alternative would be using a FormLayout where you may provide
a component as label and therefor you can provide "whatever you want".
E.g. use an icon and add a title attribute to get some simple tool-tip
from the browser:
new FormLayout().tap{
addFormItem( // XXX
new TextField(),
new Span(
new Text("The Label"),
VaadinIcon.QUESTION_CIRCLE.create().tap{
setSize('12px')
setColor('blue')
element.tap{
setAttribute("title", "The Help")
style.tap{
set('padding-left', '4px')
}
}
}
)
)
}

Hide overflowing elements in a row and add a show more button

I would like to display a list of avatar chips in a row, if it is not enough room for all the avatars I would like to hide the overflowing ones and add a show more button instead. Do you know if a component like this exists for flutter?
See the picture above, if the items exceeds the space a (+5) button is shown, if this one is clicked I want to replace the list with a wrapped list that shows all the avatars.
Is it best to write a new layout component to accomplish this?

Set prompt text to the center of TextArea control in JavaFX

I was wondering if there is a way to set prompt text location in TextArea.
Basically I am trying to create the similar effect as ListView Placeholder does. It is just to keep consistency in UI, so that everything mostly would look similar.
Any suggestions with this.
I think you can only do this by a dirty hack:
Set alignment to center.
Depending on your desired behavior either add a focus listener which sets the alignment to left again when focused and back to center when focus left.
text.focusedProperty().addListener((p,o,n)->{
if(n){
text.setAlignment(Pos.CENTER_LEFT);
}else {
text.setAlignment(Pos.CENTER);
}
});
Or add a keylistener to get the left aligned text while typing(and a focus-left listener to reset it if needed, eg. empty)
setOnKeyPressed(e->text.setAlignment(Pos.CENTER_LEFT));

Resources