I want to code a splash screen which, after clicking in a presentation´s image start to do an animation (over the image) and, 5 seconds after, go to a Login page.
I tried to find the solution of it, but the answer use to be related with a specific plataform.
My idea is to code it over cross plataform.
After researching, I found the solution coming from Xamarin offical page (animation´s samples) and another page (for the delay) I don´t remember the site...
I´m posting this question and answer because I think could be really interesting for the community.
Button startButton = new Button() { Image = "splashlogo.png", BackgroundColor = Xamarin.Forms.Color.Transparent, HorizontalOptions = Xamarin.Forms.LayoutOptions.Center, Scale = 3.5};
startButton.Clicked += async (object sender, EventArgs e) =>
{
var parentAnimation = new Animation();
var scaleUpAnimation = new Animation(v => startButton.Scale = v, 1, 2, Easing.SpringIn);
var rotateAnimation = new Animation(v => startButton.Rotation = v, 0, 360);
var scaleDownAnimation = new Animation(v => startButton.Scale = v, 2, 1, Easing.SpringOut);
parentAnimation.Add(0, 0.5, scaleUpAnimation);
parentAnimation.Add(0, 1, rotateAnimation);
parentAnimation.Add(0.5, 1, scaleDownAnimation);
parentAnimation.Commit(startButton, "ChildAnimations", 16, 4000, null);
await Task.Delay(5000);
await App.Current.MainPage.Navigation.PushModalAsync(new Login());
};
public static async Task Sleep(int ms)
{
await Task.Delay(ms);
}
Related
I want to use UIViewPropertyAnimator in Xamarin.iOS, but my project is actually part of Xamarin Forms. I created a dependency service and tried the following:
var renderer = Platform.GetRenderer(view);
var uiCubicTimingParameters = new UICubicTimingParameters(new CGPoint(x: 0.4, y: 0), new CGPoint(x: 0.2, y: 1));
var uiViewPropertyAnimator = new UIViewPropertyAnimator(duration, uiCubicTimingParameters);
uiViewPropertyAnimator.AddAnimations(() =>
{
renderer.NativeView.Transform = CGAffineTransform.MakeTranslation(300, 0);
});
uiViewPropertyAnimator.StartAnimation();
The problem with this approach is that it's directly updating the native view, but Xamarin Forms view is no longer in sync. I noticed some weird UI issues because of this.
What's the right way to use UIViewPropertyAnimator in the case of Xamarin Forms?
Before starting the animation , first set its initial Transform , and don't forget to notify Forms of the final change when animation complete .
Refer to the following code
public async Task TranslateViewAsync(View view)
{
var finished = false;
CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
{
var renderer = Platform.GetRenderer(view);
renderer.NativeView.Transform = CGAffineTransform.MakeTranslation(375, 0);
var uiViewPropertyAnimator = new UIViewPropertyAnimator(0.3, UIViewAnimationCurve.EaseOut, () =>
{
renderer.NativeView.Transform = CGAffineTransform.MakeTranslation(0, 0);
});
uiViewPropertyAnimator.AddCompletion(p =>
{
finished = true;
});
uiViewPropertyAnimator.StartAnimation();
});
while (!finished)
await Task.Delay(10);
}
Refer to https://github.com/xamarin/Xamarin.Forms/issues/6999#issuecomment-542488010 .
I have two Buttons on top of my screen .. Button A and Button B.. ByDefault button A will be selected and below that a view with all details related to Button A. When user clicks on Button B , the view will move to left and new view having the details related to button B will come from right with fade in and fade out animation...
Current Status- I am able to change the View on Button Click by hiding one and unhiding other.. But I am stuck with Animation..
Can You Please help me out.
You can use a parent/child-based Animation to control the slide and fade and have them properly sync'd
void RunAnim(Color disableColor, Color backgroundColor, bool disable)
{
new Animation
{
{ 0, 1, new Animation (v => view1.Opacity = v, disable ? 1 : 0, disable ? 0 : 1) },
{ 0, 1, new Animation (v => view1.TranslationX = v, disable ? 0 : -view1.Width, disable ? -view1.Width : 0) },
{ 0, 1, new Animation (v => view2.TranslationX = v, disable ? view1.Width : 0, disable ? 0 : view1.Width) },
{ 0, 1, new Animation (v => view2.Opacity = v, disable ? 0 : 1, disable ? 1 : 0) },
}.Commit(this, "viewAnim", 16, 1000, Easing.CubicInOut, (v, c) =>
{
physicalButton.IsEnabled = !disable;
physicalButton.BackgroundColor = disableColor;
networkButton.IsEnabled = disable;
networkButton.BackgroundColor = backgroundColor;
});
}
void Physical_Clicked(object sender, EventArgs e)
{
var disableColor = Color.Navy;
var backgroundColor = Color.Transparent;
var disable = true;
RunAnim(disableColor, backgroundColor, disable);
}
void Network_Clicked(object sender, EventArgs e)
{
var disableColor = Color.Transparent;
var backgroundColor = Color.Navy;
var disable = false;
RunAnim(disableColor, backgroundColor, disable);
}
Note: The gif looks janky, but the animation is smooth...
First, in your page
private readonly ScreenMetrics _metrics;
private readonly int _formsWidth;
private readonly int _formsHeight;
public MainPage()
{
InitializeComponent();
//calculate screen size, to use in animations
_metrics = DeviceDisplay.ScreenMetrics;
_formsWidth = Convert.ToInt32(_metrics.Width / _metrics.Density);
_formsHeight = Convert.ToInt32(_metrics.Height / _metrics.Density);
}
In OnAppearing, translate the elements you want outside the screen
protected override async void OnAppearing()
{
base.OnAppearing();
await Task.WhenAll(
//translate to the left side of the device, negative
YourViewLeftSide.TranslateTo(_formsWidth, 0, 0, null),
//translate to the right side of the device, negative
YourViewRightSide.TranslateTo(-_formsWidth, 0, 0, null)
);
}
On the button that animates left view
async void OnButton1Clicked(object sender, EventArgs args)
{
//animate left side
YourViewLeftSide.TranslateTo(0, 0, 400, Easing.CubicInOut),
}
On the button that animates right view
async void OnButton2Clicked(object sender, EventArgs args)
{
//animate right side
YourViewRightSide.TranslateTo(0, 0, 400, Easing.CubicInOut),
}
Now you can adapt and customize to your needs!
Finally I used CarouselView to achieve this Functionality
UPDATE:
I've tried implementing this in an App.cs method called OpenCameraScanner (you would call this on click of a button on the page from which you want to scan):
App.cs
------------------------------------------------
public static ZXingScannerPage ScanPage;
public static ZXing.Result ScanResult;
public static async void OpenCameraScanner()
{
ScanPage = new ZXingScannerPage(customOverlay: customOverlay);
ScanPage.OnScanResult += (result) =>
{
ScanPage.IsScanning = false;
ScanResult = result;
Device.BeginInvokeOnMainThread(() =>
{
App.CurrentApp.CurrentPage.Navigation.PopModalAsync();
App.CurrentApp.CurrentPage.DisplayAlert("Scanned Barcode", result.Text, "OK");
});
};
var scanPage = new NavigationPage(ScanPage);
await App.CurrentApp.CurrentPage.Navigation.PushModalAsync(ScanPage);
}
However, when this method is called, the screen that opens is blank white, and you can't see the camera view behind it. Not sure why?
I'm using ZXing.Mobile in a Xamarin.Forms project (for iOS right now) for camera scanning functionality on an iPad.
Currently, I have it working great with the following 2 lines:
var scanner = new ZXing.Mobile.MobileBarcodeScanner();
var result = await scanner.Scan();
However, when the camera is open to scan, it takes up the entire iPad screen, which is really big.
Question: Is there a way to adjust the size of the camera overlay? (so that it's not full screen)
I see that the scanner.Scan() method takes an optional options parameter of type ZXing.Mobile.MobileBarcodeScanningOptions - I tried playing around with that, but the only possible relevant option there is a CameraResolutionSelector - but I'm having a really hard time finding any documentation on that.
There is a ZXing sample app that shows how to embed the ZXingScannerView and ZXingDefaultOverlay into a Xamarin.Form's Grid:
https://github.com/Redth/ZXing.Net.Mobile/blob/master/Samples/Forms/Core/CustomScanPage.cs
public CustomScanPage () : base ()
{
zxing = new ZXingScannerView
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
AutomationId = "zxingScannerView",
};
zxing.OnScanResult += (result) =>
Device.BeginInvokeOnMainThread (async () => {
// Stop analysis until we navigate away so we don't keep reading barcodes
zxing.IsAnalyzing = false;
// Show an alert
await DisplayAlert ("Scanned Barcode", result.Text, "OK");
// Navigate away
await Navigation.PopAsync ();
});
overlay = new ZXingDefaultOverlay
{
TopText = "Hold your phone up to the barcode",
BottomText = "Scanning will happen automatically",
ShowFlashButton = zxing.HasTorch,
AutomationId = "zxingDefaultOverlay",
};
overlay.FlashButtonClicked += (sender, e) => {
zxing.IsTorchOn = !zxing.IsTorchOn;
};
var grid = new Grid
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
};
grid.Children.Add(zxing);
grid.Children.Add(overlay);
// The root page of your application
Content = grid;
}
i am showing images from server. In server image is changing in every second. I want that in my application image should be change automatically after one second.M new in windows 7 programming. Kindly suggest me where i am lacking in concept. M using this code.
This process will start when i will tab on my image.
private void image1_Tap(object sender, GestureEventArgs e)
{
System.Windows.Threading.DispatcherTimer dt = new System.Windows.Threading.DispatcherTimer();
dt.Interval = new TimeSpan(0, 0, 0, 0, 1000); // 500 Milliseconds
dt.Tick += new EventHandler(dt_Tick);
dt.Start();
}
This is calling this method .
void dt_Tick(object sender, EventArgs e)
{
status.Text = "chking" + counter++;
// Do Stuff here.
image1.Source = null;
Uri imgUri = new Uri(base_url,UriKind.Absolute);
BitmapImage BI = new BitmapImage(imgUri);
int H = BI.PixelHeight;
int w = BI.PixelWidth;
image1.Source = BI;
}
In this code my Counter is working fine and status.Text is sucessfully change in every second. But image is changing once after that its not changing.
Kinldy suggest me where i am commiting mistake.
Thanks in advance
Gaurav Gupta
I think you should declare System.Windows.Threading.DispatcherTimer dt = new System.Windows.Threading.DispatcherTimer(); as a member variable instead of declaring it in the images tap event.
I do the same thing when grabbing images from a camera in my wp8 app. I hold the URL including the current datetime-value as a url-param in my viewmodel. When i want to refresh, i just reset my URL-property.
Here's my sample:
this.MyUrlProperty = string.Format("{0}?timestamp={1:yyyy-MM-dd HH:mm:ss:fff}", _originalCameraUrl, DateTime.Now);
Works great for me...
I have to do a slide show off images stored in my isolated storage.. but i am beginner in windows phone and i have some dificulties.. i already know how to present the images, or show the images in the screen.. but i want to present the images 2 seconds each one.. theres some funcionalty to define the time to reproduce? Any example?
IsolatedStorageFileStream stream = new IsolatedStorageFileStream(name_image, FileMode.Open, myIsolatedStorage);
var image = new BitmapImage();
image.SetSource(stream);
image1.Source = image;
This is how i open the image. I have a foreach with 5 name of images then i open each one.. but i want to see the images 2 seconds..
You could make the current thread sleep for 2 seconds:
System.Threading.Thread.Sleep(2000);
As the last sentence in the foreach body. It is not very neat, but it will do the job.
A better way is to use Reactive Extension.
First take a look at my answer in this post. It tells you what dlls you will need as well as some useful links.
Basically you need to store you images in a collection and then use Rx (GenerateWithTime) to create a observable sequence with time dimension based on the collection. Finally you call a method to add one image and subscribe it to the observable sequence.
Here is one working example,
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
// create a collection to store your 5 images
var images = new List<Image>
{
new Image() { Source = new BitmapImage(new Uri("/ApplicationIcon.png", UriKind.Relative)), Width = 120, Height = 120 },
new Image() { Source = new BitmapImage(new Uri("/ApplicationIcon.png", UriKind.Relative)), Width = 120, Height = 120 },
new Image() { Source = new BitmapImage(new Uri("/ApplicationIcon.png", UriKind.Relative)), Width = 120, Height = 120 },
new Image() { Source = new BitmapImage(new Uri("/ApplicationIcon.png", UriKind.Relative)), Width = 120, Height = 120 },
new Image() { Source = new BitmapImage(new Uri("/ApplicationIcon.png", UriKind.Relative)), Width = 120, Height = 120 }
};
// create a time dimension (2 seconds) to the generated sequence
IObservable<Image> getImages = Observable.GenerateWithTime(0, i => i <= images.Count - 1, i => images[i], _ => TimeSpan.FromSeconds(2), i => ++i);
// subscribe the DisplayOneImage handler to the sequence
getImages.ObserveOnDispatcher().Subscribe(DisplayOneImage);
}
private void DisplayOneImage(Image image)
{
// MyItems is an ItemsControl on the UI
this.MyItems.Items.Add(image);
}
Hope this helps. :)