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
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.
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.
We have an app that shows a splash screen which shows some data so we have a custom splash screen. Also because of historic reasons all app initialization happens on the UI thread, so my solution for that was to show the splash screen in a separate STA thread.
private void ShowSplashScreen()
{
var mainDispatcher = Dispatcher.CurrentDispatcher;
var splashScreenThread = new Thread(() =>
{
new SplashScreen().Show();
_splashScreenThreadDispatcher = Dispatcher.CurrentDispatcher;
Dispatcher.Run();
});
splashScreenThread.SetApartmentState(ApartmentState.STA);
splashScreenThread.Start();
}
private void CloseSplashScreen()
{
_splashScreenThreadDispatcher.InvokeShutdown();
}
And then when initialization is done this runs
var mw = new MainWindow();
Application.Current.MainWindow = mw;
mw.Show();
CloseSplashScreen();
mw.Activate();
This works fine in normal desktop mode => the main window shows, the splash screen closes and the main window is visible.
However when I switch windows to tablet mode and launch the app from the start screen, when the main window shows it only flashes and goes to background again and it shows the start screen.
If I don't close the splash then all is still visible, but that's not an option of course.
I tried various things already with topmost, different orders of calling me.Show(), mw.Activate(), me.Focus(), setting focus in Closing handler of splash screen, but nothing seems to work.
Any ideas on how this can be fixed? In production the app is only used on tablets so it's a must have for us.
Regards
Stan
I fixed it by using a popup instead of a window for the splash screen. A popup does not require an owner or parent so it's possible to use it, and when the popup is closed the start screen doesn't go in front of the main window.
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.
RTM version of the developer tools.
I am building an app. In parts of the app I have some text provided by a web service, I take this text and process it to make the URLs in the text act as hyperlinks.
The container for this is a wrap panel.
<wrap:WrapPanel x:Name="PostMessage2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
Then in the constructor of the page I have this simple code.
PostMessage2.Children.Add(new HyperlinkButton()
{
Content = new TextBlock()
{
Text = "test url",
Foreground = new SolidColorBrush(Colors.White)
},
NavigateUri = new Uri("http://www.google.com/")
});
(I know this code is will not open an IE session and navigate to the Url)
Now when I run this program, I will not see anything visible on the screen, but if I tap the screen where the start of the url should be, then it will try to navigate to the url (which causes an exception as the navigation isn't handled correctly).
If I add a Textblock before and after the URL the test in those blocks is visible, and they will be separated by approximately 3 spaces, which if you tap the middle of this it will try to navigate to the url.
So my question is why are the hyper-links not visible but they are active as you can tap them, am I missing some obvious property or setting?
Thanks in advance for help.
You don't need to set the Content of the HyperlinkButton to be a TextBlock. It's expecting a string and you can set the Foreground color on the HLB:
PostMessage2.Children.Add(new HyperlinkButton()
{
Content = "test url",
Foreground = new SolidColorBrush(Colors.White),
NavigateUri = new Uri("http://www.google.com/")
});