public class SplashPage : ContentPage
{
Image splashImage;
public SplashPage()
{
NavigationPage.SetHasNavigationBar(this, false);
var sub = new AbsoluteLayout();
splashImage = new Image
{
Source = "Logo.png",
WidthRequest = 100,
HeightRequest = 100
};
AbsoluteLayout.SetLayoutFlags(splashImage, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(splashImage,new Rectangle(0.5,0.5,AbsoluteLayout.AutoSize,AbsoluteLayout.AutoSize));
sub.Children.Add(splashImage);
this.BackgroundColor = Color.FromHex("#429de3");
}
protected override async void OnAppearing()
{
base.OnAppearing();
await splashImage.ScaleTo(1, 2000);
await splashImage.ScaleTo(0.9, 1500,Easing.Linear);
await splashImage.ScaleTo(150, 1200, Easing.Linear);
Application.Current.MainPage = new NavigationPage(new Page1());
}
}
I recently started studying xamarin and decided to make a splash screen, everything seems to work, the screensaver itself is there, but there is no logo on the screensaver itself, although I threw it into the drawable folder for android and into resources in iOS.
The problem is that you haven't set the content of the page. You've added an image to the layout, but you haven't set the pages's Content to that layout.
Adding:
Content = sub;
will fix your problem.
If I could offer a couple of suggestions to help you debug this sort of thing in future.
A good way to test layout code is to set the background colour on individual elements. There's a great library called Debug Rainbows, that'll do a lot of the work for you.
Also, try and avoid using the more complex layouts, unless you've got a good reason to do so. A simple ContentView or StackLayout would suffice here.
The Xamarin Content Page's Content property is just a View, so there's no reason you could just set the page's content to a full screen image - if you wanted to.
Have fun.
Related
I have this code in AppDelegate.cs function FinishedLaunching :
UINavigationBar.Appearance.BackgroundColor= Color.FromHex("07987f").ToUIColor();
UINavigationBar.Appearance.BarTintColor = Color.FromHex("07987f").ToUIColor();
UINavigationBar.Appearance.TintColor = Color.White.ToUIColor();
UINavigationBar.Appearance.TitleTextAttributes = new UIStringAttributes { ForegroundColor = UIColor.White };
Before update Xamarin.Forms 4.8 to 5.0 this code worked for every navbar but now only show white color. TintColor and TextColor working fine. What should be the problem?
IMAGE:
You can set the color in Xamarin.forms when creating the NavigationPage:
MainPage = new NavigationPage(new MainPage()) {
BackgroundColor = Color.FromHex("07987f"),
BarBackgroundColor = Color.FromHex("07987f")
};
I also see a thread in Github about this issue and you can wait the response there:
UINavigationBar BackgroundColor can no longer be changed
You should try to specify it with Xamarin.Forms, using NavigationPage class.
It is certain that some code applies the color AFTER your code and thus you need to either disable it (if possible) or override it further down the line (as described above).
For iOS 15, there is a known issue with the navbar color. You can override the default behavior by setting the color in your AppDeligate.cs file. This will affect every page:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
//A bug with iOS 15 results in the backgorund color not being set on the main appshell nav so we need to force it here
var appearance = new UINavigationBarAppearance()
{
BackgroundColor = UIColor.FromRGB(144, 191, 110),
ShadowColor = UIColor.FromRGB(144, 191, 110),
};
UINavigationBar.Appearance.StandardAppearance = appearance;
UINavigationBar.Appearance.ScrollEdgeAppearance = appearance;
}
Both the StandardAppearance and the ScrollEdgeAppearence must be set the same. More info: https://developer.apple.com/forums/thread/682420
I create a SplashPage.cs in my Xamarin App, code:
public class SplashPage : ContentPage
{
Image splashImage;
public SplashPage()
{
NavigationPage.SetHasNavigationBar(this, false);
var sub = new AbsoluteLayout();
splashImage = new Image
{
Source = "logo.png",
WidthRequest = 100,
HeightRequest = 100
};
AbsoluteLayout.SetLayoutFlags(splashImage, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(splashImage, new Rectangle(0.5, 0.5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
sub.Children.Add(splashImage);
this.BackgroundColor = Color.FromHex("#ffff");
this.Content = sub;
}
protected override async void OnAppearing()
{
base.OnAppearing();
await splashImage.ScaleTo(1, 2000);
await splashImage.ScaleTo(0.9, 1500, Easing.Linear);
await splashImage.ScaleTo(150, 1200, Easing.Linear);
Application.Current.MainPage = new NavigationPage(new LoginPage());
}
}
Then in App.xaml.cs
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new SplashPage());
}
Directory in Android is Resources/drawable/logo.png
Directory for IOS is Resources/logo.png
When I compile app in a android phone splash load correctly, but when I try to use in IOS it just no load my icon, only show empty page. I'm doing something wrong?
Yes,this is often the case when you are using images that are not formatted correctly or are very complex.And I've had similar problems before.
Vector graphics are highly recommended in ios.
I have tested this question, when i use a vector image , it worked properly both in ios and android.
Note: You can try it using the following image.
Main purpose of the splash screen is give some time to load application and its components. In case of Xamarin.Forms app, this time is used to load Xamarin runtime.
Now, your splash screen it self is using Xamarin.Forms component ContentPage. So it can only be displayed after Xamarin runtime is completely loaded.
Best way is to implement splash screen the native way for iOS and Android.
Here is a good tutorial about how to implement splash screen natively on iOS and Android.
I have a WPF application and I cannot figure out a way to switch pages, even create multiple pages. All of the questions related to this topic only show how to switch, not create AND switch.
I have already tried to look up the solution, but no proper answer shows up.
Try
this.NavigationService.Navigate(new PageName());
Or
this.NavigationService?.Navigate(new PageName()); //To check if it's not null
Edit:Sorry, I didn't understand your question correctly.
As I know, you can't just create and navigate to a page. Why can't you just create a page, design it however you want, and then navigate?
Edit2: After some research, I found that you can create your own class and inherit it from Window class.
public class MyPage: Window
{
this.WindowStyle = WindowStyle.SingleBorderWindow;
//Add grid
this.RootGrid = new Grid()
{
//Add TextBox
TextBox TextBox_Test = new TextBox()
{ Text = "ABC",
Background = Brushes.Yellow,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Top
};
this.RootGrid.Children.Add(TextBox_Test);
}
}
You can add rows/columns as well.
this.RootGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(20) });
this.RootGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width= new GridWidth(20) });
Then you can navigate to MyPage page as I told.
Hope this helps.
What is the optimal solution to design big screens and tablets?
the view looks good on phones but when on tablets or big screens, the buttons and text entries looks stretched and unprofessional.
I can add padding but is there a better solution than that?
I see that the new pre-release of Xamarin forms version 3 doesn't support #medai. But does it account for this issue in another way?
The Xamarin.Forms Page class has a SizeChanged event we can use to determine the available screen-size at runtime. We can adjust the UI based on the Width or Height of the screen.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
SizeChanged += MainPageSizeChanged;
}
void MainPageSizeChanged(object sender, EventArgs e)
{
imgMonkey.WidthRequest = Math.Min(this.Width, 400);
}
}
And Xamarin.Forms provides a static Idiom property on the Device class that we can use to check the device type.
if (Device.Idiom == TargetIdiom.Phone)
{
buttonAbout.HeightRequest = 25;
buttonAbout.WidthRequest = 40;
}
else
{
buttonAbout.HeightRequest = 40;
buttonAbout.WidthRequest = 70;
}
Detail refer to Adaptive UI with Xamarin.Forms.
You can use VisualStateManager to achieve this task.
Find more information on how to get started at https://xamarinhelp.com/visualstatemanager-xamarin-forms-phase-1/
I am trying to allow the users of my Xamarin.Android application to pick an image from their gallery and upload it to the server. The image, once picked, should first be shown in the upload form, and then converted into base64 and sent to the remote web application.
My app uses only one activity containing a FrameLayout, which gets filled with Fragments. The fragment that should handle the module (which is dynamic and depends on a schema it receives from the server) is instantiating the selection control like this:
private View BuildImageUploader()
{
LinearLayout lay = new LinearLayout(Context);
lay.Orientation = Orientation.Horizontal;
lay.LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
(lay.LayoutParameters as LinearLayout.LayoutParams).SetMargins(0, 30, 0, 0);
ImageView img = new ImageView(Context);
var par = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent, 0.8f);
par.Gravity = GravityFlags.Center;
par.TopMargin = 5;
img.LayoutParameters = par;
Button btn = new Button(Context);
btn.LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent, 0.2f);
btn.Text = "Scegli";
btn.Click += (s, e) =>
{
Intent intent = new Intent();
intent.SetType("image/*");
intent.SetAction(Intent.ActionGetContent);
StartActivityForResult(Intent.CreateChooser(intent, "Scegli un'immagine"), 0);
};
lay.AddView(img);
lay.AddView(btn);
return lay;
}
I put the same override of OnActivityCreated in both my fragment and MainActivity:
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
}
Yes, it does absolutely nothing and there is currently no way to get the image back, but I plan to handle that with events. The overrides are still empty because I'm testing them by putting breakpoints in them, to check which one gets called. And guess what? None. OnActivityResult is never called neither in the activity nor in the fragment. What am I doing wrong?
Extra info - what I tried so far (none worked):
Changing the request code (the second parameter of StartActivityForResult) to something different - I tried 1, -1 and some random 4 digits numbers as well
Moving the call to StartActivityForResult inside a method in class MainActivity
Changing the event handler lambda into an actual method
Finally, I would like to emphasize that the image picking phase works like a charm; I can see the gallery and select an image. The problem is that nothing happens after that: OnActivityResult isn't called, and I verified this with breakpoints. Thanks to whoever is willing to help, I need this for work and I'm quite desperate now, so I guess any solution will do.
EDIT: I was asked to include the code that handles the control drawing. I can't include it all (it's more than 1000 lines long and all the other controls work anyway), so I will show the part concerning this specific control:
private void ShowItem(LinearLayout container, DynamicFieldSchemaItem item)
{
GuiControlType type = GuiControlType.GetGuiControlTypeById(item.SystemGuiControlId);
List<View> toAdd = new List<View>();
switch(type.Enum)
{
// Various cases for other controls...
case GuiControlTypeEnum.UploadImage:
toAdd.Add(BuildImageUploader());
break;
}
foreach (View view in toAdd)
container.AddView(view);
}
Here, container is used because the controls are divided in tabs, thus the application creates a separate LinearLayout for each of those tabs and then adds controls to it via ShowItem, called on every item received from the server.
UPDATE: while I was testing an unrelated functionality on a different device, I accidentally tapped on the uploader button, closed it, and the Activity's OnActivityResult breakpoint was toggled. This means that the problem is with my device. I have a OnePlus One with the stock LineageOS file browser and gallery. Could I solve this problem for my device somehow, in case anybody else is running the app with this setup?
1) Start in Fragment, receive results in Activity: use Activity.StartActivityForResult()
2) Start in Fragment, receive results in Fragment: use StartActivityForResult(), and in the Activity's OnActivityResult() call base.OnActivityResult(requestCode, resultCode, data);
Base on the codes you provided, looks like you want to use 2), receive results in Fragment, so, please add OnActivityResult() in your fragment.