Xamarin.Forms - make background image visible through toolbar - c#

I want every page in my app to have a transparent toolbar at the top, and a background image that covers the entire page.
In the App.xaml.cs I have written the following:
MainPage = new NavigationPage(new MDMaster())
{
BarBackgroundColor = Color.Transparent,
BackgroundImage = "background_1.png"
};
This will correctly make the toolbar transparent, however the background image is not shown. It's possible for me to add a background color but not a background image.
MDMaster is the master component of a MasterDetailPage. On the MDMaster page I set the Detail page like so:
Detail = new NavigationPage(new ProfilePage())
{
BarBackgroundColor = Color.Transparent,
BackgroundImage = "background_1.png"
};
This does not even show the background image either.
On the ProfilePage, I can write:
public ProfilePage()
{
InitializeComponent();
this.BackgroundImage = "background_1.png";
}
This will show the background image, however it will not cover the area behind the toolbar even though it's transparent. It ends up looking like this:

First, as #Yuri S suggested, you don't need to wrap your MasterDetailPage with NavigationPage. Just set the MasterDetailPage as the MainPage is OK.
Then when you are setting the background image to the root MasterDetailPage, the reason why the background image is not showing is because the top NavigationPage is not transparent and it's hiding the background image.
So to fix the problem, you need to set the BackgroundColor of NavigationPage to transparent too:
public App()
{
InitializeComponent();
MainPage = new MasterDetailPage()
{
Master=new MainPage(),
Detail=new NavigationPage(new Detail())
{
BarBackgroundColor=Color.Transparent,
BackgroundColor=Color.Transparent
},
BackgroundImage="tianyuan.jpg"
};
}
Then it will show like this:
If you don't want your status bar to show like above, you can set it manually in Droid project:
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
//set the status bar color
Window.SetStatusBarColor(Android.Graphics.Color.Black);
}
}
And it will show like this:

Related

Does not display a logo Xamarin

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.

Xamarin.Forms 5.0 NavBar BackgroudColor not changing on IOS

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

Winforms Transparent Panel Control - Hover, Click Through and Redraw Issues

I have followed a number of posts here and on other sites for creating a Transparent Panel control for WinForms that has "real" transparency (i.e. it does not just inherit the background color of the container it is in).
Here is my derived panel class so you can see how I did it:
namespace TransparencyPOC
{
public partial class TransPictureBox : Panel
{
public TransPictureBox()
{
InitializeComponent();
}
public TransPictureBox(IContainer container)
{
container.Add(this);
InitializeComponent();
}
protected override void OnPaintBackground(PaintEventArgs e)
{
//do nothing
}
protected override void OnMove(EventArgs e)
{
RecreateHandle();
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20; //WS_EX_TRANSPARENT
return cp;
}
}
private Image m_Image;
public Image Image
{
get
{
return m_Image;
}
set
{
m_Image = value;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
Bitmap bmp = new Bitmap(m_Image);
bmp.MakeTransparent();
g.DrawImage(bmp, 0, 0, 100, 100);
g.Dispose();
}
}
}
I am using this panel control to hold a PNG with a transparent background, and need to be able to position it above other controls, such as other transparent panels, buttons, etc.
Two issues:
If I position this panel partially over a button control, I can only click the button in the areas where the panel doesn't overlap the control. Is there any way that I can make the hover and click events pass through the transparent panel so that when I hover or click anywhere over the button, even parts of the button that are obscured by the PNG that the button receives those clicks? Assume that this needs to be dynamic, i.e. I won't know what control the image is positioned above, just want it to be able to pass the hover and clicks through to whatever is beneath it.
When I do hover over part of the button that is not covered by the panel, the button repaints itself above the transparent panel (see image below for before and after)
Before Hovering:
After Hovering:
Questions:
Can I allow the button to be hoverable/clickable through the transparent panel? Ideally, I would want any visible portion of the underlying button to be hoverable/clickable, but if that's not doable, then I'd want it to be clickable/hoverable as if there was nothing above it.
Can I prevent the button from being redrawn over the panel when I do hover over it, and/or trigger a repaint of the panel when this happens?
Thank you in advance!

IOS don't show logo in splash screen

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.

C# transparent PNG for buttons, panels...how?

I have being searching a lot, seen a few examples but they don't work at least for me. This is what I need: in my application I need to use transparent PNG icons for the toolbars and also for draggable visual objects representations, ie, 72x72 "page" icon which can be dragged around and possibly over all elements in the client area. For the first I was thinking about using a button, set its BackImage to the transparent PNG and put BackColor as "transparent": it won't work, the button always show a solid color behind. As for the panel, the same problem: I can put a transparent PNG as background image but the control never looks "transparent" where the PNG has transparent areas. I think the same with a picturebox and any other control allowing image backgrounds. So I guess, it is really about making a control's background transparent...Any ideas?
I don't care if I need to create some sort of custom "image button" or "image panel" --whatever-- to have truely PNG transparent buttons, panels, etc! Also, please note, it is about PNG transparency, using the alpha channel, not transparent pixels, which at this ages, sucks IMHO for decent GUIs.
Cheers
litium
Ok I found the following code whith works not only for panels but also for buttons and I guess other controls --except PictureBox:
public class TransparentPanel : Panel <==change to Button for instance, and works
{
Timer Wriggler = new Timer();
public TransparentPanel()
{
Wriggler.Tick += new EventHandler(TickHandler);
this.Wriggler.Interval = 500;
this.Wriggler.Enabled = true;
}
protected void TickHandler(object sender, EventArgs e)
{
this.InvalidateEx();
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
protected void InvalidateEx()
{
if (Parent == null)
{
return;
}
Rectangle rc = new Rectangle(this.Location, this.Size);
Parent.Invalidate(rc, true);
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
// Do not allow the background to be painted
}
}
Works for me 100%! Doesn't seems to work for PictureBoxes.

Categories