I don't need toolbar, title and all that. But I need back button (back button icon with a string back to Home). There is a status bar in iOS. Can I put back btn with icon and text in statusbar? I have seen it in fb. If I go to messenger from fb, back to facebook is in the status bar with time battery icons etc. Can we do that in codenameone?
Back button in status bar (not in title bar) in iOS
What I have done so far. I think this is similar to what have been suggested in the answer. It works in android but in iOS I want to keep the back btn in the status bar with time, battery icons etc.
t = new Toolbar();
t.setUIID("TitleAreaa");
f.setToolBar(t);
Style s = UIManager.getInstance().getComponentStyle("Button");
s.setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM));
Image backtoRTN = FontImage.createMaterial(FontImage.MATERIAL_ARROW_BACK, s);
back = new Command("Back to RTN", backtoRTN) {
#Override
public void actionPerformed(ActionEvent evt) {
showForm("Main", this);
}
};
back.putClientProperty("uiid", "BacktoRTN");
f.setBackCommand(back);
t.addCommandToLeftBar(back);
The right thing to do here is something similar to what we do in this demo
Notice that the smiley is part of the UI and not part of the title...
The trick for doing this is simple override this method in your Form:
#Override
protected void initGlobalToolbar() {
Toolbar tb = new Toolbar(true);
tb.setUIID("Container");
setToolbar(tb);
getTitleArea().setUIID("Container");
}
That creates a toolbar that is layered (floats on top of the UI). Setting it to Container UIID makes it invisible.
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);
In my Codenameone app i have built a side menu, but i have 2 cosmetic issues with it.
When i swipe from the left and i lift my finger in the screen space, slightly further than the menu finishes, the menu snaps back. It doesn't snap back if i lift my finger in the space the menu will expand to. Is there a way to make the side menu stay on the screen when i swipe?
My main page has a vertically scrollable container. When i open the side menu, it doesn't disable my main page so i am still able to scroll my main page container by moving my finger on the space to the right of the menu. Are we able to disable the main page content by default when the menu is open?
For ref, my menu is along the design of this tutorial, with a very simple example being:
public void start() {
if (current != null) {
current.show();
return;
}
Form hi = new Form("Hi World", BoxLayout.y());
hi.add(new Label("Hi World"));
Toolbar t = new Toolbar();
hi.setToolbar(t);
t.setTitle("Title");
Label logoLabel = new Label("");
logoLabel.setTextPosition(Label.BOTTOM);
logoLabel.setText("label text here");
t.addComponentToSideMenu(logoLabel);
hi.show();
}
Thanks
The point of closing back seems to be hardcoded to a quarter of the screen here: https://github.com/codenameone/CodenameOne/blob/master/CodenameOne/src/com/codename1/ui/Toolbar.java#L1380
There might be other points in the code that implement this logic. It might be possible to change that to make that logic configurable via theme constants. But right now this is hard coded.
While swiping a form, the growing left part of the screen is just white until the swiping is done, when the "back-to" form finally is painted. Is this by design? I expected the "back-to" form either to be gradually revealed, or to slide in from the left.
On iOS and Android, the form being swiped also seems to turn white, so the whole screen is white until the swiping is over. This is not the case with the simulator, however, where you can see the form until it's swiped all the way out.
Code to reproduce the behaviour:
Form redForm = new Form("Red Form");
redForm.getAllStyles().setBgColor(0xff0000);
Button btnToBlueForm = new Button("Go to blue form");
redForm.add(btnToBlueForm);
Form blueForm = new Form("Blue Form");
blueForm.getAllStyles().setBgColor(0x0000ff);
LazyValue<Form> lazyRedForm = (Object... args) -> redForm;
SwipeBackSupport.bindBack(blueForm, lazyRedForm);
btnToBlueForm.addActionListener((ActionListener<ActionEvent>) (ActionEvent evt) -> {
blueForm.show();
SwipeBackSupport.bindBack(blueForm, lazyRedForm);
});
redForm.show();
Press the button in the red form. The blue form now appears. Swipe back and observe the effects.
That's because of the SlideFade mode in the transition. If you switch it to Slide it should work as expected with the background. Here's a version of your code that works as you would expect by applying the style to the content pane:
Form redForm = new Form("Red Form");
redForm.getContentPane().getAllStyles().setBgColor(0xff0000);
redForm.getContentPane().getAllStyles().setBgTransparency(255);
Button btnToBlueForm = new Button("Go to blue form");
redForm.add(btnToBlueForm);
Form blueForm = new Form("Blue Form");
blueForm.getContentPane().getAllStyles().setBgColor(0x0000ff);
blueForm.getContentPane().getAllStyles().setBgTransparency(255);
LazyValue<Form> lazyRedForm = (Object... args) -> redForm;
SwipeBackSupport.bindBack(blueForm, lazyRedForm);
btnToBlueForm.addActionListener((ActionListener<ActionEvent>) (ActionEvent evt) -> {
blueForm.show();
SwipeBackSupport.bindBack(blueForm, lazyRedForm);
});
redForm.show();
The reason this works as opposed to the original code is that SlideFade is two separate transitions one moving/fading the title and the other sliding the content pane alone. Since the content pane is transparent the background isn't painted as we assume it's the form background. By setting the content pane color/opacity we get the exact same effect at a layer the SlideFade will "see".
I would like to make it so that a button highlights when it is pressed, and un-highlights (?) when it is released. Right now I have implemented the pressed part by overriding the pressed function in the subclass of Button, and the released part by overriding the two released functions. However, I have an issue that when you press the button, drag the mouse and release it outside of the Button, the button stays highlighted. I wanted to try doing the same thing by overriding dragFinished but this has not been working for me, so I am looking for another way.
#Override
public void pressed(){
super.pressed();
Style style = getParent().getStyle();
style.setBorder(Border.createLineBorder(1, 1416152));
updateParentStyle(style);
}
#Override
public void released(){
super.released();
Style style = getParent().getStyle();
style.setBorder(Border.createEmpty());
updateParentStyle(style);
}
You don't need to do that.
Just override the "Pressed" state of the button in the theme to have a different border which is the "right way" or alternatively do what you did thru the style:
myButton.getPressedStyle().setBorder(Border.createLineBorder(1, 1416152));
myButton.getUnselectedStyle().setBorder(Border.createEmpty());
myButton.getSelectedStyle().setBorder(Border.createEmpty());
I'm developing a reporting dashboard application using W8 Metro UI style application. The application has a dark theme, so most of the screen is black. I'm using the WebView control to display SSRS .rdl reports from our report server (which all have black backgrounds). The problem I'm seeing is that when I navigate to a new report, the WebView control flashes white for a split second and then loads the new report. To get around this, I tried putting an Easing opacity animation on the WebView control to make it fade out, load the report, and then fade back in. However, no matter what I try, I can't get the flickering to go away.
I then tried putting a black rectangle on top of the WebView and fading that one in and out... still no luck. The WebView is always on top at runtime, meaning I can't put any control on top of it. Does anyone know of a way around this?
I breifly looked into the WebView.Transitions, but couldn't find many resources on this. Could this be my answer?
EDIT:
Event to load the new report:
void ItemListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Create a WebViewBrush of the content currently loaded in the WebView
WebViewBrush b = new WebViewBrush();
b.SourceName = "WebView1";
b.Redraw();
Rectangle1.Fill = b;
// Hide the WebView
WebView1.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
// Navigate to the new report
var selectedItem = ItemListView.SelectedItem;
WebView1.Navigate(((Report)selectedItem).ReportUri);
}
void WebView1_LoadCompleted(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
// Show the new report
WebView1.Visibility = Windows.UI.Xaml.Visibility.Visible;
Rectangle1.Fill = new SolidColorBrush(Colors.Transparent);
}
This is just the way WebView works because internally its loading the trident COM control into a separate hwnd. The workaround is to set Visibility to Hidden on the webview and instead show a webviewbrush which isn't interactive but does integrate with the rest of your UI so it can be animated, etc