I am using this code to display an AlertDialog on a network error:
var builder = new AlertDialog.Builder(this);
builder.SetMessage(error);
builder.SetCancelable(false);
builder.SetPositiveButton("OK", delegate { });
builder.Show();
However, it looks like this:
Problems:
The current view is not displayed behind the alertdialog, it's just white.
It aligned to the top, not center
The theme or font color is wrong making the text hard to read.
I am using Theme.DeviceDefault.Light as theme for the activity:
[Activity (Label = "xxx", Theme = "#style/MyAppTheme", MainLauncher = true)]
...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyAppTheme" parent="#android:style/Theme.DeviceDefault.Light">
</style>
</resources>
How to fix this? Have tried to insert MyAppTheme as second argument to AlertDialog.Builder(this, Resource.Style.MyAppTheme) but with no change in the UI.
Solved it. Used
var builder = new AlertDialog.Builder(this, Android.App.AlertDialog.ThemeHoloLight);
and it looks better. I also used Activity.ShowDialog() and placed my AlertDialog code inside
protected override Dialog OnCreateDialog(int id, Bundle args)
not sure that it did any difference.
Good blogpost: http://blog.ostebaronen.dk/2013/02/using-dialogs-in-mono-for-android.html
Related
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.
I've defined custom bottomview to make custom tabbar shell in android project.
To make this, I created a new render and a new xml file to define the graphics.
But there is a problem, I have margin but the background under the bottom view is black and I don't know how I can edit this color.
This is my code:
public class MyShellBottomNavViewAppearanceTracker : IShellBottomNavViewAppearanceTracker
{
public void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
{
bottomView.SetBackgroundResource(Resource.Drawable.bottomBack);
if (bottomView.LayoutParameters is LinearLayout.LayoutParams layoutParams)
{
layoutParams.SetMargins(30, 0, 30, 0);
bottomView.LayoutParameters = layoutParams;
}
}
}
This is my xml of shell:
<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#fff555" />
<corners android:topLeftRadius="15dp"
android:topRightRadius="15dp"
android:bottomLeftRadius="15dp"
android:bottomRightRadius="15dp"
/>
<padding android:top="5dp" android:bottom="5dp"/>
</shape>
The result appears with background of view gray, shell with yellow color and Black in background but for the last one I don't know how I can edit (make gray as rest of view).
Screen about background tab bar is black and not gray as rest of the view
How can I specify the tab bar background (out of margin)?
You could try to get Parent of bottomView,then set its background color to gray.
public void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
{
bottomView.SetBackgroundResource(Resource.Drawable.bottombackground);
Android.Views.View view = (Android.Views.View)bottomView.Parent;
view.SetBackgroundColor(Android.Graphics.Color.Gray);
if (bottomView.LayoutParameters is LinearLayout.LayoutParams layoutParams)
{
layoutParams.SetMargins(30, 0, 30, 0);
bottomView.LayoutParameters = layoutParams;
}
}
I can enable fonts for Label, entry, etc(Xamarin.Forms UI fields) like this...
<Style TargetType="Label">
<Setter Property="FontFamily">
<Setter.Value>
<OnPlatform x:TypeArguments="x:String">
<On Platform="iOS" Value="Montserrat_Regular" />
<On Platform="Android" Value="Montserrat_Regular.ttf#Montserrat_Regular" />
</OnPlatform>
</Setter.Value>
</Setter>
</Style>
But it doesn't apply font for title & content of dialog boxes, list in pickers n many more places like that(Internal iOS UI fields).
I override the default font of android to achieve the above issue, but the problem is with iOS, I can't find any solution for it in C#.
There are many solutions present in objective-c & swift.
Objective-c Solution
Swift 5 solution
Another Solution
Can someone help me convert these codes or provide any other solution?
EDIT -
Dialog Boxes are Device Specific, Xamarin.Forms code won't work individually on it.
iOS Dialog box -
Device.BeginInvokeOnMainThread( () =>
{
UIAlertController alert = UIAlertController.Create(title, message, UIAlertControllerStyle.Alert);
alert.AddAction(UIAlertAction.Create(cancel, UIAlertActionStyle.Cancel, a => task.SetResult(false)));
alert.AddAction(UIAlertAction.Create(ok, UIAlertActionStyle.Default, a => task.SetResult(true)));
UIViewController vc = GetViewController(UIApplication.SharedApplication.KeyWindow.RootViewController);
if (TargetIdiom.Tablet == Device.Idiom)
{
vc.ModalPresentationStyle = UIModalPresentationStyle.Popover;
}
vc.PresentModalViewController(alert, true);
});
Android Dialog box with fix for font -
Device.BeginInvokeOnMainThread( () =>
{
AlertDialog dialog = new AlertDialog.Builder(Forms.Context, Resource.Style.Base_Animation_AppCompat_Tooltip).SetTitle(title).SetMessage(content).SetPositiveButton(ok, delegate { task.SetResult(true); })
.SetNegativeButton(cancel, delegate { task.SetResult(false); }).Show();
TextView textView = (TextView)dialog.FindViewById(Android.Resource.Id.Message);
textView.SetTypeface(Typeface.CreateFromAsset(Forms.Context.Assets, "Montserrat_Regular.ttf"), TypefaceStyle.Normal);
var _buttonOK = (Button)dialog.FindViewById(Android.Resource.Id.Button1);
_buttonOK.SetTypeface(Typeface.CreateFromAsset(Forms.Context.Assets, "Montserrat_Regular.ttf"), TypefaceStyle.Normal);
var _buttonCancel = (Button)dialog.FindViewById(Android.Resource.Id.Button2);
_buttonCancel.SetTypeface(Typeface.CreateFromAsset(Forms.Context.Assets, "Montserrat_Regular.ttf"), TypefaceStyle.Normal);
});
You can creat a Custom Label Renderer to achieve that.
Create the CustomLabelRenderer in iOS solution:
[assembly: ExportRenderer(typeof(Label), typeof(CustomLabelRenderer))]
namespace XamarinTableView.iOS
{
public class CustomLabelRenderer: LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
Control.Font = UIFont.FromName("Montserrat-Regular", (nfloat)Element.FontSize);
}
}
}
You will see the typeof(Label), it means will work for all the Label of Xamarin Forms in iOS device.
==============================Update=================================
I have checked in local site and make it works for UILable. You need to add Montserrat-Regular.ttf file inside the iOS solution correctly.
For example:
And also need to add this .ttf in info.plist as follows:
<key>UIAppFonts</key>
<array>
<string>Montserrat-Regular.ttf</string>
</array>
Then the renderer code will work.
In addition, you can use typeof(CustomLabel) to use the special effect for special Label.
=================================Update #2================================
If need to works for UIAlertController ,have a try with follow ways. However, there is no way to modify the font of Button in iOS, it only works for Title and Message.
Device.BeginInvokeOnMainThread(() =>
{
UIAlertController alert = UIAlertController.Create(title, message, UIAlertControllerStyle.Alert);
var titleAttributedString = new NSAttributedString(title,
new CTStringAttributes()
{
ForegroundColorFromContext = true,
Font = new CTFont("Montserrat-Regular", 24)
});
alert.SetValueForKey(titleAttributedString, new NSString("attributedTitle"));
var messageAttributedString = new NSAttributedString(message,
new CTStringAttributes()
{
ForegroundColorFromContext = true,
Font = new CTFont("Montserrat-Regular", 24)
});
alert.SetValueForKey(messageAttributedString, new NSString("attributedMessage"));
UIAlertAction cancleAction = UIAlertAction.Create("Cancle", UIAlertActionStyle.Cancel, a => Console.WriteLine("cancle"));
alert.AddAction(cancleAction);
UIAlertAction okAction = UIAlertAction.Create("OK", UIAlertActionStyle.Cancel, a => Console.WriteLine("OK"));
alert.AddAction(okAction);
UIViewController vc = GetViewController(UIApplication.SharedApplication.KeyWindow.RootViewController);
if (TargetIdiom.Tablet == Device.Idiom)
{
vc.ModalPresentationStyle = UIModalPresentationStyle.Popover;
}
vc.PresentModalViewController(alert, true);
});
The effect:
you can't override default font, you need to set font on individual components for now, I'll let you know if i found any better solution
So I'm a bit of a newb in Android. I've read a few tutorials but found it extensively complicated to understand. I was hoping someone can help me understand on how to implement Animations to views on the current context I'm working on (noob friendly).
Let's say this is my .axml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/top_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="vertical" />
Now this is my activity (Not exactly but enough information to know what I want to do:
private LinearLayout _topContainer;
private IDictionary<string, FrameLayout> _framelayoutViewsDictionary = new Dictionary<string, FrameLayout>();
private LinearLayout.LayoutParams layoutParams;
protected override void OnCreate(Bundle bundle)
{
//SetContentView and other stuff...
layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent, 1);
_topContainer = FindViewById<LinearLayout>(Resource.Id.top_container);
}
public void CreateFirstVideoPlayer
{
_framelayoutViewsDictionary.Add(Constants.Views.TOP_FRAMELAYOUT, new FrameLayout(this)
{
Id = 1,
LayoutParameters = layoutParams
});
var fragmentManager = FragmentManager.BeginTransaction();
fragmentManager.Add(_framelayoutViewsDictionary[Constants.Views.TOP_FRAMELAYOUT].Id, /*Create New MediaPlayer Here*/, Constants.FragmentTag.TOP_FRAGMENT);
fragmentManager.Commit();
_topContainer.AddView(_framelayoutViewsDictionary[Constants.Views.TOP_FRAMELAYOUT]);
}
public void CreateSecondVideoPlayer
{
_framelayoutViewsDictionary.Add(Constants.Views.BOTTOM_FRAMELAYOUT, new FrameLayout(this)
{
Id = 2,
LayoutParameters = layoutParams
});
var fragmentManager = FragmentManager.BeginTransaction();
fragmentManager.Add(_framelayoutViewsDictionary[Constants.Views.BOTTOM_FRAMELAYOUT].Id, /*Create New MediaPlayer Here*/, Constants.FragmentTag.BOTTOM_FRAGMENT);
fragmentManager.Commit();
_topContainer.AddView(_framelayoutViewsDictionary[Constants.Views.BOTTOM_FRAMELAYOUT]);
}
As you can see. I'm programmatically creating a new FrameLayout, adding a fragment on top. And then putting that FrameLayout on top view which is a LinearLayout. Now when I add the second FrameLayout. The first FrameLayout is halved and the second one is added. So now each FrameLayout is taking 50:50 space. So what I want to do is. When the second FrameLayout is added, I want the first FrameLayout to animate so it slowly moves upwards to the top half of the screen instead of instantly appearing on the top. And when I remove the second FrameLayout the first FrameLayout will slowly animate back to the centre of the screen.
Hope this all makes sense. If you need more info please comment!
Using the Support Libraries to perform a fragment slide in/out is as easy as setting the Fragment's custom animations to the built-in resource abc_slide_in_bottom and abc_slide_out_bottom animations.
Example:
SupportFragmentManager
.BeginTransaction()
.SetCustomAnimations(
Resource.Animation.abc_slide_in_bottom,
Resource.Animation.abc_slide_out_bottom,
Resource.Animation.abc_slide_in_bottom,
Resource.Animation.abc_slide_out_bottom)
.AddToBackStack(count.ToString())
.Add(Resource.Id.linearLayout1, new AFragmentSubClass(), count.ToString())
.Commit();
Is there any chance that I can remove the title bar of the app in Xamarin.Forms? I am working on a Xamarin.Forms Portable project. I tried a lot of solutions, but neither worked, I couldn't even start the app.
First attempt I tried adding this to my AndroidManifest.xml, didn't work:
android:theme="#android:style/Theme.NoTitleBar"
Second attempt I tried creating a styles.xml in Resources/values, which was:
<?xml version="1.0" encoding="utf-8" ?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Theme.Default" parent="#android:style/Theme"></style>
<style name="Theme.NoTitle" parent="#android:style/Theme.NoTitleBar"></style>
<style name="Theme.FullScreen" parent="#android:style/Theme.NoTitleBar.Fullscreen"></style>
</resources>
And then I added this to my AndroidManifest.xml (didn't work either)
android:theme="#style/Theme.NoTitle"
Third attempt I tried adding this to my OnCreate method in MainActivity.cs (didn't work).
RequestWindowFeature(WindowFeatures.NoTitle);
Can anyone help me with this?
If you want to remove the title bar on the initial page, the quickest and easiest way to do it is to go to to the contentpage heading in your XAML for the page and type
NavigationPage.HasNavigationBar="False"
so the XAML would like something like this
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="YourClass.YourPage"
NavigationPage.HasNavigationBar="False">
This can be done in PCL:
var page = new LoginPage();
NavigationPage.SetHasNavigationBar(page, false); // call this method every time before you push a page (no title bar)
await navigation.PushAsync(page);
If you are using old FormsApplicationActivity,
try, add this in OnCreate(Bundle bundle) method
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle)
Forms.SetTitleBarVisibility(AndroidTitleBarVisibility.Never);
Forms.Init(this, bundle);
}
This one seems do the app wide setting, but I am not so sure, as I don't use FormsApplicationActivity anymore.
Using the latest version of Xamarin.Forms I found that if you use:
await Navigation.PushAsync(new NextPage())
//Title on NextPage is displayed
await Navigation.PushModalAsync(new NextPage())
//Title on NextPage is not displayed
Nathan
i had this problem before and my solution was adding this line of code to the MainPage.xaml NavigationPage.HasNavigationBar="False"
<?xml version="1.0" encoding="utf-8" ?>
<xf:BottomBarPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xf="clr-namespace:BottomBar.XamarinForms;assembly=BottomBar.XamarinForms"
xmlns:local="clr-namespace:App;assembly=App"
NavigationPage.HasNavigationBar="False" <-- This line !-->
x:Class="App.MainPage">
and it worked for me !
Theme = "#android:style/Theme.NoTitleBar"
.
using Android.App;
using Android.OS;
using Android.Webkit;
using Android.Views; // Webkit required for WebView
namespace LoadWebPage {
[Activity(Label = "LoadWebPage", MainLauncher = true, Icon = "#drawable/icon", Theme = "#android:style/Theme.NoTitleBar")]
public class Activity1 : Activity {
protected override void OnCreate (Bundle bundle)
For iOS this single line (e.g. in the constructor of the page) works just fine.
NavigationPage.SetHasNavigationBar(page, false);
But Android is ignoring it, also when put in the XAML of the page.
As mentioned above by Bonelol this method has to be called each time before you push a page.
I use Prism, so I can't access the creation and push of a page.
So I just created a custom renderer for NavigationPage and put this line there. Maybe this will help someone else.
[assembly: ExportRenderer(typeof(NavigationPage), typeof(CustomNavigationRenderer))]
namespace MyApp.Droid.Renderer
{
public class CustomNavigationRenderer : NavigationPageRenderer
{
public CustomNavigationRenderer(Context context) : base(context)
{
}
protected override Task<bool> OnPushAsync(Page view, bool animated)
{
NavigationPage.SetHasNavigationBar(view, false);
return base.OnPushAsync(view, animated);
}
}
}
Try This:
private ActionBar ab;
protected override void OnCreate(Bundle savedInstanceState)
{
try
{
base.OnCreate(savedInstanceState);
ab = this.ActionBar;
ab.Hide();
}
catch (Exception ex)
{
}
}
Try this one, just found it in one of view xaml in flyout tab
Shell.NavBarIsVisible="False"
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="YourClass.Views.YourPage" Shell.NavBarIsVisible="False">