How to use activity_main layout as a widget on xamarin? - xamarin

I have a xamarin project and my main purpose is creating a widget by using activity_main layout and my activity main layout includes tabbed pages such as Tab1 , Tab2 and Tab3 . That is why i want to show them on widget . According to my researches i need some xml file to create a widget on android . My xml file like this.
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="294dip"
android:minHeight="72dip"
android:resizeMode="horizontal"
android:minResizeWidth="144dip"
android:updatePeriodMillis="86400000"
android:initialLayout="#layout/activity_main"/>
I added activity_main as a initialLayout and i did some arrangement in the bag. My appwidget class like this .
[BroadcastReceiver(Label = "Widget")]
[IntentFilter(new string[] { "android.appwidget.action.APPWIDGET_UPDATE" })]
[MetaData("android.appwidget.provider", Resource = "#xml/widget_word")]
class AppWidget : AppWidgetProvider
{
public override void OnUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
context.StartService(new Intent(context, typeof(UpdateService)));
}
}
My updateService like this .
public override void OnStart(Intent intent, int startId)
{
// Build the widget update for today
RemoteViews updateViews = buildUpdate(this);
// Push update for this widget to the home screen
ComponentName thisWidget = new ComponentName(this, Java.Lang.Class.FromType(typeof(AppWidget)).Name);
AppWidgetManager manager = AppWidgetManager.GetInstance(this);
manager.UpdateAppWidget(thisWidget, updateViews);
}
public override IBinder OnBind(Intent intent)
{
throw new NotImplementedException();
}
public RemoteViews buildUpdate(Context context)
{
// Build an update that holds the updated widget contents
var updateViews = new RemoteViews(context.PackageName, Resource.Layout.activity_main);
return updateViews;
}
I am using fragments to display tab1 , tab2 , tab3 . If I add fragment axml file to the initialLayout it works fine . But it shows only tab1 . I feel like i should use activity_main to display 3 tabs on widget. Please help !

You cannot use bottomNavigationView in the appwidget,
If you set it you will get follow error.
Creating the App Widget layout is simple if you're familiar with Layouts. However, you must be aware that App Widget layouts are based on RemoteViews, which do not support every kind of layout or view widget.
A RemoteViews object (and, consequently, an App Widget) can support the following layout classes:
FrameLayout
LinearLayout
RelativeLayout
GridLayout
And the following widget classes:
AnalogClock
Button
Chronometer
ImageButton
ImageView
ProgressBar
TextView
ViewFlipper
ListView
GridView
StackView
AdapterViewFlipper
Descendants of these classes are not supported.
Here is Google article about it.
https://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout

Related

Xamarin Forms iOS TitleBarTextColor not changing

To change the TitleBarTextColor so far I tried a lot and my code now does change the back button color and the area on the very top of the screen, but the title!
in my AppDelegate FinishedLaunching function (it's after Forms.Init() and before LoadApplication()):
UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes
{
TextColor = UIColor.White
});
In my ViewModel:
(App.Current.MainPage as NavigationPage).BarBackgroundColor = Color.FromHex("#990000");
(App.Current.MainPage as NavigationPage).BarTextColor = Color.White;
And this is how I'm navigating between the pages (not all the pages):
await _navigationService.NavigateAsync(new Uri("http://wwww.x.com/NavigationPage/TabbedNavigationPage?selectedTab=XPage/Document", UriKind.Absolute));
I even try to call the ViewModel code after the Prism navigation but it doesn't work... I'm a beginner and don't fully comprehend Prism and or Xamarin Forms.
[EDIT] -> I also tried to create a new class and inherit it from NavigationPage, set the BarTextColor in its constructor and use that class in the navigation like this: await _navigationService.NavigateAsync(new Uri("http://wwww.x.com/NEWCLASSCREATED/TabbedNavigationPage?selectedTab=XPage/Document", UriKind.Absolute)); But, as you may know, it is still not working.
Here's a Image ;)
imageToSeeThatImNotLying
Thank you for your support!
So I finnaly managed to work this out...
What I had to do was to create a custom Content Page because all the other solutions wasn't working. So I created this custom renderer only in my iOS project:
[assembly: ExportRenderer(typeof(ContentPage), typeof(CustomContentPageRenderer))]
namespace TestProject.iOS.Bll.Utils.Renderers
{
public class CustomContentPageRenderer : PageRenderer
{
public override void DidMoveToParentViewController(UIViewController parent)
{
base.WillMoveToParentViewController(parent);
var titleView = new UITextView();
var page = this.Element as ContentPage;
try
{
if (!string.IsNullOrEmpty(page.Title))
{
titleView.Text = page.Title;
titleView.TextColor = UIColor.White;
titleView.Font = UIFont.SystemFontOfSize(17, UIFontWeight.Regular);
var bgColor = page.BackgroundColor;
titleView.BackgroundColor = UIColor.FromRGBA((int)bgColor.R, (int)bgColor.G, (int)bgColor.B, 0);
parent.NavigationItem.TitleView = titleView;
parent.NavigationItem.TitleView.ContentMode = UIViewContentMode.ScaleAspectFit;
}
}
catch (Exception e)
{
}
}
}
}
And I also removed all the code that I puted before in my AppDelegate file and in the App.xaml.cs file as well. I left the codes from the ViewModels because it was changing the back button to white, and I deleted the new NagivationPage class that I created before.
I'm going to explain why I did some of the things that you saw there:
To change the Title I created a UITextView() and set it to my NavigationItem.TitleView of the parent page. I set titleView.Text = page.Title; because my original page already have a title, so I'm just reusing it. And the backgroundcolor I had to do all of that so the backgroundcolor property works just in the way that I wanted.
And this DidMoveToParentViewController function was just so it can do all that before NavigationAsync from Prism.

Xamarin Iconize IconTabbedPage Example

Can someone provide an example of how to use the IconTabbedPage in Iconize, preferably in Xaml? I have an IconTabbedPage with IconNavigation pages as children, all defined in Xaml. I then set the Icon property of the subpages by specifiying the font awesome name (“fa-home”). I tried to set the title as well, but neither of these will render the icon. I have search (a lot) for examples of the IconTabbedPage but couldn’t find any in Xaml. Additional bonus if you can provide an example of how to use the icons in a list cell context action.
Looking into #Niklas Code, you can create a tabbed page with a base class that inherits from IconTabbedPage , then your xaml will look like this.
<icon:IconTabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:icon="clr-namespace:Plugin.Iconize;assembly=Plugin.Iconize"
....
>
<icon:IconTabbedPage.Children>
<ContentPage Title="Build" Icon="md-build">
</ContentPage>
</icon:IconTabbedPage.Children>
I hope it will help somebody
I think you can take a look on Sample on GitHub
[\[assembly: XamlCompilation(XamlCompilationOptions.Compile)\]
namespace Iconize.FormsSample
{
public class App : Application
{
public App()
{
// The root page of your application
var tabbedPage = new IconTabbedPage { Title = "Iconize" };
foreach (var module in Plugin.Iconize.Iconize.Modules)
{
tabbedPage.Children.Add(new Page1
{
BindingContext = new ModuleWrapper(module),
Icon = module.Keys.FirstOrDefault()
});
}
MainPage = new IconNavigationPage(tabbedPage);
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}][1]

ARCGis Xamarin - MapView from previous page displays after navigating to new page

I have a 'main' map page from which the user can either add data to the map or click on existing data to see the details. This is done with PushModalAsync() where I navigate to a new page. My problem is in both of those new pages I have a new map with a new MapView that is 'underneath' the MapView from the 'main' page. Both the MapView and Map itself are new objects on the secondary pages.
After navigating to my new pages, the previous MapView shows in the area of the screen where it existed (on 'main' page) where my new MapView also exists. In other words, on my new map pages my map is laid out differently and partially sits higher in the layout than the 'main' map does. The part that sits higher is the only part of the new map that is visible and I can interact with. The part that sits on the same area is the 'main' map view and I cannot interact with it and it blocks my new map.
I tried this with PushAsync as well (not modal) and nothing changed. How is one supposed to have multiple maps in an app across multiple pages? Is this even possible with ArcGIS? This app used to be with Google Maps/Apple and the exact same layout worked just fine.
Edit: Code here (with irrelevant parts removed) This page is navigated to from another page with a map on it wherein this map is covered if it is laid out in the same area of the first map. From this page I navigate to a 3rd page where both maps show up. Removal works successfully, however when I try to add I get an error saying I cannot add a null child to a view group:
public partial class EventDetails : ContentPage
{
public Xamarin.Forms.Grid MapGrid = new Xamarin.Forms.Grid()
{
RowDefinitions =
{
new RowDefinition { Height = 220 },
new RowDefinition { Height = GridLength.Auto }
},
ColumnDefinitions =
{
new ColumnDefinition { Width = 500 }
},
HorizontalOptions = LayoutOptions.Center
};
public Map DetailMap;
public MapView MyDetailMapView = new MapView();
public EventDetails(MapLog eventDetails, string strMapType)
{
DetailMap = new Map(BasemapType.ImageryWithLabels, eventDetails.Latitude, eventDetails.Longitude, iMapDetail);
MyDetailMapView.Map = DetailMap;
MyDetailMapView.ViewpointChanged += MyMapView_ViewpointChanged;
var scrollView = new ScrollView
{
Content = mainStack
};
MapGrid.Children.Add(MyDetailMapView, 0, 0);
MapGrid.Children.Add(scrollView, 0, 1);
Content = MapGrid;
}
#if __ANDROID__
protected override void OnAppearing()
{
if (!MapGrid.Children.Contains(MyDetailMapView))
{
try
{
MapGrid.Children.Add(MyDetailMapView);
}
catch (Exception ex)
{
DisplayAlert("Err", ex.Message, "Ok");
}
}
base.OnAppearing();
}
protected override void OnDisappearing()
{
if (MapGrid.Children.Contains(MyDetailMapView))
MapGrid.Children.Remove(MyDetailMapView);
base.OnDisappearing();
}
#endif
}
EDIT*: I updated my Xamarin Forms version and ARCGIS Runtime and now the solution to remove/add the map does work without issue.
I had other similar problems with having two maps for android in Xamarin Forms ArcGIS and the solution was removing the MapView from the visual tree when you navigate to the new page.
You need to remove the MapView before you Navigate to the second page by:
[your parent layout].Children.Remove(MyMapView);
await Navigation.PushAsync(new SecondPage());
And in your first page you need to make sure to add the MapView back to the Visual Tree when you come back to the page:
protected override void OnAppearing()
{
if (!GridMap.Children.Contains(MyMapView))
GridMap.Children.Add(MyMapView);
base.OnAppearing();
}
That solved all my problems with two maps. Thanks to this post in ESRI forum
Navigation between 2 MapViews in Xamarin Android

Custom tab item

I need to add a custom tab item into my TabbedPage. That shouldn't be a page but an overlay view. It is "More" item for the bottom menu opening a more items menu over the currently shown page.
So far I found the following solution:
protected override void OnCurrentPageChanged()
{
base.OnCurrentPageChanged();
if (this.isInitialized)
{
if (CurrentPage.Title == "More")
{
CurrentPage = this.lastSelectedPage;
}
}
this.lastSelectedPage = CurrentPage;
}
It's enough to prevent opening the corresponding fake page. After this I need to show an overlay view and have no item how to do it from the tabbed page.
Another solution I'm working out now is to write a custom renderer for my tabbed page and manage all the custom work there. The question in this case is how to show my custom view over the existing content. I tried AddView (iOS) in the renderer but getting runtime exception.
public override void ItemSelected(UITabBar tabbar, UITabBarItem item)
{
base.ItemSelected(tabbar, item);
var view = new UILabel()
{
Text = "Test"
};
View.Add(view);
}

How do I override the Xamarin Forms TabbedPage item fonts for iOS?

Wanting to achieve a consistent look for my Xamarin Forms app, I need to know how to change the font for the tabbed page tab bar icons. Using UITabBarItem.Appearance as the iOS API would suggest does not appear to have any effect. What's necessary to do this?
U need to write a custom renderer like this one , take a clue from below code ! it has what u r seeking
[assembly: ExportRenderer(typeof(ExtendedTabbedPage), typeof(TabbedPageCustom))]
namespace App.iOS
{
public class TabbedPageCustom : TabbedRenderer
{
public TabbedPageCustom ()
{
TabBar.TintColor = UIKit.UIColor.White;
TabBar.BarTintColor = UIKit.UIColor.White;
TabBar.BackgroundColor = UIKit.UIColor.Red;
}
protected override void OnElementChanged (VisualElementChangedEventArgs e)
{
base.OnElementChanged (e);
// Set Text Font for unselected tab states
UITextAttributes normalTextAttributes = new UITextAttributes();
normalTextAttributes.Font = UIFont.FromName("ChalkboardSE-Light", 20.0F); // unselected
normalTextAttributes.TextColor = UIKit.UIColor.Blue;
UITabBarItem.Appearance.SetTitleTextAttributes(normalTextAttributes, UIControlState.Normal);
}
public override UIViewController SelectedViewController {
get {
UITextAttributes selectedTextAttributes = new UITextAttributes();
selectedTextAttributes.Font = UIFont.FromName("ChalkboardSE-Bold", 20.0F); // SELECTED
if (base.SelectedViewController != null)
{
base.SelectedViewController.TabBarItem.SetTitleTextAttributes(selectedTextAttributes, UIControlState.Normal);
}
return base.SelectedViewController;
}
set {
base.SelectedViewController = value;
foreach (UIViewController viewController in base.ViewControllers)
{
UITextAttributes normalTextAttributes = new UITextAttributes();
normalTextAttributes.Font = UIFont.FromName("ChalkboardSE-Light", 20.0F); // unselected
normalTextAttributes.TextColor = UIKit.UIColor.Blue;
viewController.TabBarItem.SetTitleTextAttributes(normalTextAttributes, UIControlState.Normal);
}
}
}
}
}
This was a particularly interesting problem. I tried:
UITabBarItem.Appearance
Using the UITabBarItem.Appearance.SetTitleTextAttributes method to update the UITextAttribute to my font (size 9.0f) for UIControlState.Normal. This didn't appear to make any difference.
UINavigationBar.Appearance
I found out that setting UINavigationBar.Appearance.SetTitleTextAttributes would update both the UINavigationBar text appearance as well as the UITabBarItem text appearance.
Which was a problem because the tabbed page item font size was far too large.
Customizing the TabbedRenderer
Inspired by a sample I saw somewhere, I subclassed TabbedRenderer in the iOS project.
I tried overriding the settor for TabbedRenderer.SelectedViewController property and loop through the ViewControllers property to set their items. The icons would display with the standard font, but once the user changed the tab they would all update to the desired font. Almost there!
I then tried overriding AddChildViewController and updating that controller's TabBarItem after it was added which ended up having no effect. The TabBarItem for the added page was being updated at some point after the controller was added.
Eventually I found out that overriding ViewWillAppear and setting the appearance for all the tab bar items at that time seemed to do the job I desired.
I've included a sample in this gist.

Resources