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".
Related
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.
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();
This creates a SwipeableContainer inside a Tab, but the swipe gesture is always detected by both the SwipeableContainer and the Tab (i.e. It shows the button under SwipeableContainer and move the page back to the left tab simultaneously when my finger swipes from left to right), which makes it very difficult to press the button behind it.
Is there any way to detect the gesture on SwipeableContainer only?
Tabs main_tab = new Tabs();
Container query_container;
Container history_container;
history_container = new Container(new BoxLayout(BoxLayout.Y_AXIS));
MultiButton his_btn = new MultiButton("History");
Button delete_btn = new Button("delete");
SwipeableContainer his_list_container = new SwipeableContainer(delete_btn,his_btn);
history_container.add(his_list_container);
main_tab.addTab("query", query_icon, query_container);
main_tab.addTab("history", history_icon, history_container);
I think that you can just remove the Swipe Gesture for the Tabs using the following method:
main_tab_.setSwipeActivated(false);
From the codenameone documentation:
public void setSwipeActivated(boolean swipeActivated)
Setter method for swipe mode
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.
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