Here is my problem : I would like to create a specific component with the camera and an image representing a target overlaying the VideoControl's view.
First I would like to display the camera in a MainScreen with a TitleBar.
Here is my code :
public class ScanScreen extends MainScreen {
private ScanScreen()
{
super();
this.vfm = new VerticalFieldManager(Field.FIELD_VCENTER);
this.controller = new ScanController(this);
//Initialize the player.
try
{
this.player = javax.microedition.media.Manager.createPlayer("capture://video?encoding=jpeg&width=1024&height=768");
this.player.realize();
this.player.prefetch();
this.videoControl = (VideoControl) this.player.getControl("VideoControl");
if(this.videoControl != null)
{
// Initialize the field where the content of the camera shall be displayed.
Field videoField = (Field) this.videoControl.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field");
// Display the video control.
this.videoControl.setDisplayFullScreen(true);
this.videoControl.setVisible(true);
// Start the player.
this.player.start();
// Add the video field to the main screen.
if(videoField != null)
{
this.vfm.add(videoField);
}
else
{
LabelField sorry = new LabelField("Sorry, we cannot use camera right now.");
this.vfm.add(sorry);
}
}
}
catch(Exception e)
{
Dialog.alert(e.toString());
}
// TODO : the camera is hiding the title bar
this.setTitle("Title");
this.add(this.vfm);
}
}
The first problem is that the view of the VideoContol is hiding my title bar. How can I fix that ?
The second thing : I have a specific rectangular image representing a target with transparency which I would like to displaying over the view of the VideoControl.
I first tried to create a new class extending Field returning the dimensions of this image and make the image displayed in the paint method (this class is "mypackage.CameraField"). Then I tried to instantiate my VideoField with the name of my new class "mypackage.CameraField" in the initDisplayMode ; but the created videoField is null.
So, is there a solution to create that kind of behaviour ? I am thinking about the native application "Video Camera" in the "Multimedia" folder that displays a VideoControl in a specific area of the screen.
Thank you.
Ok, it seems that is not possible to customize the VideoControl in any way. We must use it in fullscreen and cannot display anything on it.
Related
enter image description hereI can't find way to add button with icon to top screen menu. I don't even know name of this bar. I mean swiping down of top screen menu however your are, there are buttons like wifi, bluetooth, screen etc.(picture attached). Maybe someone know name of this bar, link to sdk or how add this button or something connected to it.
It is the Tile Service for the quick settings in the Android, you can check the official document about this.
In addition, I have done a sample to test this api and it worked well.
Just declare a class to extend the TileService, such as:
[Service(Permission = "android.permission.BIND_QUICK_SETTINGS_TILE", Icon = "#drawable/icon", Label = "mymenu", Enabled = true, Exported = true)]
[IntentFilter(new[] { "android.service.quicksettings.action.QS_TILE" })]
public class DemoTitle : TileService
{
public override void OnClick()
{
refresh();
}
public void refresh()
{
var state = QsTile.State;
state = (state == TileState.Active)?TileState.Inactive:TileState.Active;
QsTile.State = state;
QsTile.UpdateTile();
}
}
After this, you can find and add the your custom button to the quick settings when you click the editing button in the bar.
I need to preview links of pages in recyclerview . I used this Library : https://github.com/LeonardoCardoso/Android-Link-Preview but it does not work. anyone know another way ?
Based on our chat in the comments section, you want to add the preview at some position in your scroll list. In that case, you can maintain some state (eg. position) in LinkPreviewCallback. So that when the preview results are ready, based on the maintained state, you can find the exact view where preview needs to be rendered.
Create a Class and Implement LinkPreviewCallback.
class MyPreviewCallback implements LinkPreviewCallback {
int position;
public MyPreviewCallback(int position) {
super();
this.position = position;
}
#Override
public void onPre() {
}
#Override
public void onPos(SourceContent sourceContent, boolean b) {
// update adapter list item based on the position.
}
}
Pass callback to the crawler.
textCrawler.makePreview(new MyPreviewCallback(3), url); // passing position
The main idea is basically to maintain some state in your class which will let you identify the exact View to be updated with Preview.
I am newbie to Xamarin.Forms and stuck with a situation where I want to open up a popup box with my control details [e.g. View Employee Details] on click of parent page.
How can I open custom dialog box / popup using Xamarin.Forms?
Any example code will be appreciated?
Thanks in advance!
If you still want to have your popup's code in its own Page you can set up some custom renderers along the following logic.
1. A ModalPage & corresponding renderer
public class ModalPage : ContentPage { }
public class ModalPageRenderer : PageRenderer {
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
this.View.BackgroundColor = UIColor.Clear;
this.ModalPresentationStyle = UIModalPresentationStyle.OverCurrentContext;
}
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
SetElementSize (new Size (View.Bounds.Width, View.Bounds.Height));
}
}
2. HostPage
public class ModalHostPage : ContentPage, IModalHost
{
#region IModalHost implementation
public Task DisplayPageModal(Page page)
{
var displayEvent = DisplayPageModalRequested;
Task completion = null;
if (displayEvent != null)
{
var eventArgs = new DisplayPageModalRequestedEventArgs(page);
displayEvent(this, eventArgs);
completion = eventArgs.DisplayingPageTask;
}
// If there is no task, just create a new completed one
return completion ?? Task.FromResult<object>(null);
}
#endregion
public event EventHandler<DisplayPageModalRequestedEventArgs> DisplayPageModalRequested;
public sealed class DisplayPageModalRequestedEventArgs : EventArgs
{
public Task DisplayingPageTask { get; set;}
public Page PageToDisplay { get; }
public DisplayPageModalRequestedEventArgs(Page modalPage)
{
PageToDisplay = modalPage;
}
}
}
3. HostPage renderer
public class ModalHostPageRenderer: PageRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if(e.OldElement as ModalHostPage != null)
{
var hostPage = (ModalHostPage)e.OldElement;
hostPage.DisplayPageModalRequested -= OnDisplayPageModalRequested;
}
if (e.NewElement as ModalHostPage != null)
{
var hostPage = (ModalHostPage)e.NewElement;
hostPage.DisplayPageModalRequested += OnDisplayPageModalRequested;
}
}
void OnDisplayPageModalRequested(object sender, ModalHostPage.DisplayPageModalRequestedEventArgs e)
{
e.PageToDisplay.Parent = this.Element;
var renderer = RendererFactory.GetRenderer (e.PageToDisplay);
e.DisplayingPageTask = this.PresentViewControllerAsync(renderer.ViewController, true);
}
}
Then it is as simple as calling
await ModalHost.DisplayPageModal(new PopUpPage());
from your host page or in this particular case from the ViewModel behind.
What Pete said about PushModalAsync / PopModalAsync still remains valid for this solution too (which in my opinion is not a disadvantage), but your popup would appear with transparent background.
The main advantage of this approach, in my opinion, is that you can have your popup XAML/code definition separate from the host page and reuse it on any other page where you wish to show that popup.
The general purpose of what you are trying to achieve can be accomplished by using the PushModalAsync and PopModalAsync methods of Xamarin.Forms Navigation object.
The chances are that this is good enough for what you are needing - However - this isn't truely modal. I will explain after a small code snippet:-
StackLayout objStackLayout = new StackLayout()
{
};
//
Button cmdButton_LaunchModalPage = new Button();
cmdButton_LaunchModalPage.Text = "Launch Modal Window";
objStackLayout.Children.Add(cmdButton_LaunchModalPage);
//
cmdButton_LaunchModalPage.Clicked += (async (o2, e2) =>
{
ContentPage objModalPage = new ContentPage();
objModalPage.Content = await CreatePageContent_Page2();
//
await Navigation.PushModalAsync(objModalPage);
//
// Code will get executed immediately here before the page is dismissed above.
});
//
return objStackLayout;
private async Task<StackLayout> CreatePageContent_Page2()
{
StackLayout objStackLayout = new StackLayout()
{
};
//
Button cmdButton_CloseModalPage = new Button();
cmdButton_CloseModalPage.Text = "Close";
objStackLayout.Children.Add(cmdButton_CloseModalPage);
//
cmdButton_CloseModalPage.Clicked += ((o2, e2) =>
{
this.Navigation.PopModalAsync();
});
//
return objStackLayout;
}
The problem with the above is that the
await Navigation.PushModalAsync(objModalPage);
will immediately return after the animation.
Although you can't interact with the previous page, as we are displaying a new NavigationPage with a Close button shown - the parent Navigation Page is still executing behind the scenes in parallel.
So if you had any timers or anything executing these still would get called unless you stopped those.
You could also use the TaskCompletionSource approach as outlined in the following post also How can I await modal form dismissal using Xamarin.Forms?.
Note - that although you can now await the 2nd page displaying and then when that page is dismissed allowing code execution to continue on the next line - this is still not truely a modal form. Again timers or anything executing still will get called on the parent page.
Update 1:-
To have the content appear over the top of existing content then simply include it on the current page, however make this section of content invisible until you need it.
If you use an outer container such like a Grid that supports multiple child controls in the same cell, then you will be able to achieve what you want.
You will also want to use something like a filled Box with transparency that will cover the entire page also, to control the visible, see through section, that surrounds your inner content section.
I followed above approach and found it impossible to run on iOS 7.
I found this library BTProgressHUD which you can modify and use.
I Use its methods by Dependency service.
Actual library for popups.
https://github.com/nicwise/BTProgressHUD
Following example uses BTProgressHUD library internally.
https://github.com/xximjasonxx/ScorePredictForms
I am using MonoTouch.Dialog to create a settings-like page. The linq below creates a set of RootElements, each with one section that has a set of RadioEventElements (a subclass of RadioElement that I created in order to add an OnSelected event).
// initialize other phone settings by creating a radio element list for each phone setting
var elements = (from ps in PhoneSettings.Settings.Keys select (Element) new RootElement(ps, new RadioGroup(null, 0))).ToList();
// loop through the root elements we just created and create their substructure
foreach (RootElement rootElement in elements)
{
rootElement.Add(new Section()
{
(from val in PhoneSettings.Settings[rootElement.Caption].Values select (Element) new RadioEventElement(val.Name)).ToList()
});
// ...
}
One of the settings I implement is a "Theme" - which currently is simply a background color for the various screens in the app. I can style every one of the pages correctly by setting the TableView.BackgroundColor property to the desired color... Except for new DialogViewControllers that are automatically created and pushed by the parent DialogViewController when it navigates into a radio group.
Is there any way to style (or at least set the background color) of this child DialogViewController?
I need to use the assembly browser more before asking easy questions :-)
Fortunately the RootElement has a virtual method called PrepareDialogViewController for what appears to be exactly this purpose. All I had to do is create a simple subclass of RootElement and override this method to get my desired behavior.
public class ThemedRootElement : RootElement
{
public ThemedRootElement(string caption) : base (caption)
{
}
public ThemedRootElement(string caption, Func<RootElement, UIViewController> createOnSelected) : base (caption, createOnSelected)
{
}
public ThemedRootElement(string caption, int section, int element) : base (caption, section, element)
{
}
public ThemedRootElement(string caption, Group group) : base (caption, group)
{
}
protected override void PrepareDialogViewController(UIViewController dvc)
{
dvc.View.BackgroundColor = UIColorHelper.FromString(App.ViewModel.Theme.PageBackground);
base.PrepareDialogViewController(dvc);
}
}
Hopefully this helps save someone out there a litte time...
In order to get this to work, I had to override the MakeViewController method and cast the UIViewController that it normally returns to a UITableViewController, then make my edits.
protected override UIViewController MakeViewController()
{
var vc = (UITableViewController) base.MakeViewController();
vc.TableView.BackgroundView = null;
vc.View.BackgroundColor = UIColor.Red; //or whatever color you like
return vc;
}
I created for BlackberryMaps a own menu item with help of "MenuItem" and invoke Blackberry Maps. After using this Item the current location (MapView) should be send back to my Application. This works fine.
The problem is I found no solution for closing the app after using the menu Item. Is there a possibility to close Blackberry Maps? Or set my own App to foreground?
private static class MapMenuItem extends ApplicationMenuItem {
//creates a new MenuItem for Blackberry Maps and defines the action which should //happen after a click on the MenuItem
CustomDialog_GPS customDialogGps;
StartScreen startScreen;
MapMenuItem(StartScreen startScreen, CustomDialog_GPS customDialogGps) {
super(20);
this.startScreen = startScreen;
this.customDialogGps = customDialogGps;
}
public String toString() {
//creates the name for the navigation Menu
String itemName = ""+_res.getString(CUSTOMDIALOG_GPS_USE_AS_NEW_LOCATION);
return itemName;
}
public Object run(Object context) {
//defines what should happen after a click on the menu
//get the location at which the cursor is pointing at.
MapView mv = (MapView)context;
if (mv != null) {
//opens a method inside of CustomDialogGPS which handles the latitude and longitude
customDialogGps.saveAdjustedPosition(mv);
//TODO pop Screen
//Screen screen = (Screen)UiApplication.getUiApplication().getActiveScreen();
}
else {
throw new IllegalStateException("Context is null, expected a MapView instance");
}
return null;
}
}
Unfortunately you can't close another app programmatically (Actually you can if you know where is menu item to close for example) but you can foreground your app UiApplication.getApplication().requestForeground(). What is probably appropriate solution for you.
Instead of passing the user to the Maps application, which is outside your app and you have no control over it, create your own screen with a MapField in it. Using your own screen and perhaps extending the MapField class to override functions if needed, allows you to go back to the previous screen once the user selects a location.