I tried to use a com.codename1.components.FloatingActionButton in combination with a com.codename1.ui.TextArea.
Now I have two questions:
Apparently the valign is not honored - is it a bug?
The actionListener of the FloatingActionButton is not called. Is anything wrong with my usage or is it a bug?
Here is the code to demonstrate it:
public class FormFabOnText extends Form {
public FormFabOnText() {
setTitle("FormFabOnText");
setLayout(new BorderLayout());
Container contentPane = getContentPane();
contentPane.add(BorderLayout.NORTH, new SpanLabel(
"This form contains a TextArea and a FloatingActionButton combined by bindFabToContainer. "
+ "It demonstrates that the FloatingActionButton is not working in this constellation."));
TextArea textArea = new TextArea();
float iconDefaultSize = FloatingActionButton.getIconDefaultSize();
try {
FloatingActionButton.setIconDefaultSize(2.0f);
FloatingActionButton floatingActionButton = FloatingActionButton.createFAB(FontImage.MATERIAL_CLEAR);
Container containerFab = floatingActionButton.bindFabToContainer(textArea, Component.RIGHT, Component.CENTER);
floatingActionButton.addActionListener((e) -> textArea.setText(""));
contentPane.add(BorderLayout.CENTER, containerFab);
} finally {
FloatingActionButton.setIconDefaultSize(iconDefaultSize);
}
}
}
The text area has 0 height so when you valign to the center the button correctly places itself on top. Then you add it to a border layout which stretches it across but the preferred size of the text area determines the valign so it stays.
I'm not sure if there is a good workaround for that other than a bit of margin like we did in the msuikit demo.
The issue with tapping during editing is probably related to the native editing peer. Tapping inside the text area gets sent to the native layer for editing otherwise elements below might cause an issue. Text input is a peer but also a very special case.
Related
I have a scrollabillity issue in a Form, layered out by BoxLayout.y().
The form contains many Tabs (with fixed size), each tab of the Tabs can contain an image or a video (the video is inside a BorderLayout to scale it at the tab size).
If an image is shown, the scrolling up and down works correctly.
If a video is shown, the y scrolling is not possibile, I can only swipe to change the tab.
I suppose that the cause of this issue is that videos are native component (I used the Codename One API to show the videos).
How can I solve or workaround this issue? This is crucial for the app design. Thanks for the tips.
The video.setEnabled(false) workaround (Make videos scrollable) doesn't work.
I workaround in a different way, inserting the MediaPlayer container in a LayeredLayout container, and then placing a Button over the MediaPlayer. A generic empty Label doesn't work, but an empty Button works. Of course I have to override calcPreferredSize to make the MediaPlayer and the Button of the same size (or use a different approach to make them of the same size).
This allows scrolling, but prevents the tapping of the play and pause Buttons (that are over the video). I solved also this issue.
In short, this is my solution, tested on Simulator, Android and iOS (in the following code, note that videoBtnsCnt is a Container over the video, in which I inserted play and pause Buttons):
MediaPlayer mediaPlayer = new MediaPlayer(video) {
#Override
public Dimension getPreferredSize() {
return new Dimension(size, size);
}
};
Container mediaPlayerCnt = new Container(new LayeredLayout(), "NoMarginNoPadding") {
#Override
public Dimension getPreferredSize() {
return new Dimension(size, size);
}
};
mediaPlayerCnt.add(mediaPlayer);
Button allowScrollingLabel = new Button() {
#Override
public Dimension getPreferredSize() {
return new Dimension(size, size);
}
};
allowScrollingLabel.setUIID("NoMarginNoPadding");
allowScrollingLabel.addActionListener(l -> {
Component responder = videoBtnsCnt.getResponderAt(l.getX(), l.getY());
if (responder instanceof Button) {
// it can be a play button or a pause button
((Button) responder).pressed();
((Button) responder).released();
}
});
mediaPlayerCnt.add(allowScrollingLabel);
With Codename One components can change their size and this even can be animated, which is nice.
But what is the expected behaviour with shrinking Container instances, specifically if they are scrollable?
Having a Container, scrollable in the Y-axis and content that is smaller than the container the content sticks to the top. The container can be dragged and the content scrolls back to the top of the container. However, when the content shrinks and becomes smaller than the container the behaviour is - somewhat strange.
I have made an example - when the coloured components are tapped they expand. If tapped again they shrink. One can tap the green Label and it expands. Tapping it again it shrinks and everything is as of before.
However, if one taps a coloured label and scrolls any amount down before tapping it again to shrink it this is the resulting view:
Only if one then drags the scrolling container ever so lightly then the contant scrolls back to the top.
I assume this is a bug. Though I wonder - what should be the behaviour when the content shrinks beyond the scrolling containers size? Since the user might expect the component just tapped to remain where it was - can the scrolling behaviour be controlled somehow?
This is just an example but I want to build expandable "drawer" components.
Here is the code:
public class FormContentSmallerScrollableContainer extends Form {
private class LabelExpandable extends Label {
boolean expanded = false;
LabelExpandable(String aTitle, int aColor) {
super(aTitle);
getAllStyles().setBgPainter((aGraphics, aRectangle) -> {
aGraphics.setColor(aColor);
aGraphics.fillRoundRect(getX(), getY(), aRectangle.getWidth() - 1, aRectangle.getHeight() - 1, 20, 20);
});
setOpaque(true);
}
#Override
public void pointerReleased(int x, int y) {
super.pointerReleased(x, y);
expanded = !expanded;
setShouldCalcPreferredSize(true);
getParent().animateLayout(400);
}
#Override
protected Dimension calcPreferredSize() {
if (!expanded) {
return super.calcPreferredSize();
}
Dimension dimension = super.calcPreferredSize();
dimension.setHeight(Display.getInstance().getDisplayHeight());
return dimension;
}
}
public FormContentSmallerScrollableContainer() {
super("FormContentSmallerScrollableContainer");
setScrollable(false);
setLayout(new BorderLayout());
add(BorderLayout.NORTH, new Label("The container below is scrollable in the y-axis"));
Container containerScrollable = BoxLayout.encloseY(
new LabelExpandable("LabelExpandable green", 0x00ff00),
new LabelExpandable("LabelExpandable blue", 0x00c0ff));
containerScrollable.setScrollableY(true);
add(BorderLayout.CENTER, containerScrollable);
add(BorderLayout.SOUTH, new Label("The container above is scrollable in the y axis"));
}
}
This is a long standing behavior when we animate a scrollable area to what's effectively a non-scrollable area. We tried working around this in the past but couldn't find the right approach. You can file the issue on this but I'm not optimistic as it's really hard to even find a workaround for this.
In my cn1-project, the top and left line border for Label, Button and TextField are not shown on an Android 7.0 device. The simulator shows all borders correct. The issue can be easily reproduced with the code from the SignatureComponentDemo on the current cn1 version 4.x for the themes FlatXXXX which also use line borders instead of border images.
I created a new FlatBlue "Get Started App" on Intellij Idea and replaced the code for init(), start(), stop() and destroy() in MyApplication by the code from the SignatureComponentDemo.
The TextField for the name in the demo shows correctly with a line border on the simulator. One the Galaxy S7 edge with Android 7.0 the top and left border of the TextField are missing. Adding more padding for these components has no effect. Also disabling loading of native theme by setting includeNativeBool to false has no effect. The only relevant code is in the following method:
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Signature Component");
hi.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
hi.add("Enter Your Name:");
hi.add(new TextField());
hi.add("Signature:");
SignatureComponent sig = new SignatureComponent();
sig.addActionListener((evt)-> {
System.out.println("The signature was changed");
Image img = sig.getSignatureImage();
// Now we can do whatever we want with the image of this signature.
});
hi.addComponent(sig);
hi.show();
}
Is there a workaround for this issue? I need to build a table of Components using TableLayout. The table class is no option, because i need to draw borders of different color and thickness and wanted to apply these to the Containers and Components within the container using TableLayout as a layout manager.
Since adding a global Toolbar to the forms there is a strange animation bug (?) when changing forms. At hitting a Button at FormA that will invoke FormB.show() the title has an animation the lets the new form stutter in the toolbar area from the right to the left. After googling I found this:
This is pretty much the problem I face at the toolbar, only difference is the toolbar Logo I added to the center is stuttering from the right to the left to its place. After the animation is done, the form looks just like it should.
In the main I do this:
Toolbar.setGlobalToolbar(true);
In every Form I do something like this in the constructor:
menuForm = new Form(" ", new BorderLayout());
logo = res_theme.getImage("Logo_Gema_vertikal.png");
menuForm.getToolbar().getTitleComponent().setUIID("toolbar_image");
((Label)menuForm.getToolbar().getTitleComponent()).setIcon(logo);
menuForm.getToolbar().addCommandToSideMenu(homeCommand);
menuForm.getToolbar().getMenuBar().addCommand(homeCommand);
If I leave out adding the logo to the toolbar, only the Command Icons are flying from the right to the left. What is causing this? Am I using the toolbar wrong?
From your question, it's due to using the default animation which is createSlideFadeTitle. You can solve this by changing the animation of the current form and the destination form to either createCover or createSlide:
In the current form:
currentForm.setTransitionOutAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, false, 300));
nextForm.show();
And in the destination form:
nextForm.setTransitionOutAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, false, 300));
currentForm.showBack();
In my app, I can't figure out how to properly style the toolbar with my logo image.
What I want to make it look like is pretty much like the Toolbar from the "Sport1" App.
Example
So I need the back Command on the left side of the toolbar, my logo in the middle from a MultiImage out of the resource and on the right another command.
Also, I'd like to let the Toolbar get smaller with scrolling.
What I have tried so far:
res_theme = r;
Form f = new Form(" ", new BoxLayout(BoxLayout.Y_AXIS));
logo = res_theme.getImage("Logo_Gema_vertikal.png");
f.getToolbar().getTitleComponent().setUIID("toolbar_image");
Style stitle = f.getToolbar().getStyle();
stitle.setBgTransparency(0);
stitle.setBgImage(logo);
stitle.setBackgroundType(Style.BACKGROUND_IMAGE_ALIGNED_CENTER);
stitle.setPaddingUnit(Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS);
stitle.setPaddingTop(5);
So, this looks good the way it is. I dont actually need a Title, thats why I do
Form f = (" ", ...);
If I don't add a title to the form, the toolbar gets very small and squeezes the background Image from the toolbar. The centered logo from the toolbar is just for styling reasons there, it does not need to have a command. Is there a way to leave out the Title? I now have set it to completely transparent, but for me this is just a work-around.
Also, I guess rather than setting the logo as background with a centered alignment, I think it would be better to add it to the title section as Image, but I don't know if this is better or how to do it.
Now, I also want to make the Toolbar get smaller when scrolling down. I found kind of a example code in the Codename One Toolbar Documentation, but it does not work out for me, since the background Image gets removed.
This was the code for the scrolling Animation:
ComponentAnimation title = f.getToolbar().getTitleComponent().createStyleAnimation("Title", 200);
f.getAnimationManager().onTitleScrollAnimation(title);
In the example, it worked. With my toolbar it does not, I have no clue why. I also can't see, where the size of the "after scrolling toolbar" is set.
Can I add there an Image as well? Kinda like one toolbar before scrolling with my logo, then while scrolling it transforms into a smaller one with only a textlogo image?
Here is my whole code what I have tried to make it work:
Form f = new Form(" ", new BoxLayout(BoxLayout.Y_AXIS));
logo = res_theme.getImage("Logo_Gema_vertikal.png");
f.getToolbar().getTitleComponent().setUIID("toolbar_image");
Style stitle = f.getToolbar().getStyle();
stitle.setBgTransparency(0);
stitle.setBgImage(logo);
stitle.setBackgroundType(Style.BACKGROUND_IMAGE_ALIGNED_CENTER);
stitle.setPaddingUnit(Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS);
stitle.setPaddingTop(5);
f.add(new SpanLabel("asdasdasdasd");
ComponentAnimation title = f.getToolbar().getTitleComponent().createStyleAnimation("Title", 200);
f.getAnimationManager().onTitleScrollAnimation(title);
f.show();
From the example above if looks like you just want to use the image as the title instead of styling the toolbar with a background image.
Just use ((Label)toolbar.getTitleComponent()).setIcon(myImage);.