Xamarin Forms and FreshMVVM android UI issue - xamarin.forms

I use to XF and FreshMVVM framework and I have a UI issue
My code is:
App.cs
public const string NAVIGATION_LOGIN = "NavigationContainerLogin";
public const string NAVIGATION_MASTER_DETAIL = "NavigationContainterMasterDetail";
private FreshMasterDetailNavigationContainer _mainNav;
private FreshNavigationContainer _loginNav;
public App()
{
//prepare two navigation container
_mainNav = CreateMasterDetailNavigation();
_loginNav = CreateLoginNavigation();
if (Settings.IsSignedIn)
{
MainPage = _mainNav;
}
else
{
MainPage = _loginNav;
}
}
private FreshMasterDetailNavigationContainer CreateMasterDetailNavigation()
{
var masterDetailNav = new FreshMasterDetailNavigationContainer(NAVIGATION_MASTER_DETAIL);
masterDetailNav.Init("eDocine", "hamburger.png");
masterDetailNav.Master = FreshPageModelResolver.ResolvePageModel<MenuPageModel>();
masterDetailNav.Detail = new FreshNavigationContainer(FreshPageModelResolver.ResolvePageModel<HomePageModel>())
{
BarBackgroundColor = Settings.IsDoctorUser ? DataHelper.GreenCoor : DataHelper.BlueColor,
BarTextColor = Color.White
};
return masterDetailNav;
}
private FreshNavigationContainer CreateLoginNavigation()
{
return new FreshNavigationContainer(FreshPageModelResolver.ResolvePageModel<ChooseUserTypePageModel>(), NAVIGATION_LOGIN);
}
public MasterDetailPage RootPage
{
get
{
return MainPage as MasterDetailPage;
}
}
It line appears only on Android 5+
How can I solve this issue?

I found solution of this issue here

Related

Xamarin.Forms Google Services AdMob

I'm trying to implement AdMob in my Xamarin.Forms app (Android version for now). Here is what I have done so far:
Created a custom control, AdViewControl, in my shared project:
public class AdControlView : Xamarin.Forms.View
{
}
In my page in which to show the ad, I added the custom control in xaml:
xmlns:ads="clr-namespace:MyFeelingBuddyTwo.Views"
<ads:AdControlView BackgroundColor="Red"/>
In the Android project (AndroidManifest.xml), within :
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-myappid"/>
<activity android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
In the Android project still, I created an AdViewRenderer:
[assembly: ExportRenderer(typeof(MyFeelingBuddyTwo.Views.AdControlView), typeof(AdViewRenderer))]
namespace MyFeelingBuddyTwo.Droid
{
class AdViewRenderer : ViewRenderer<Views.AdControlView, AdView>
{
string adUnitId = "myadunitid";
AdSize adSize = AdSize.SmartBanner;
AdView adView;
AdView CreateAdView()
{
if (adView != null)
return adView;
adView = new AdView(Forms.Context);
adView.AdSize = adSize;
adView.AdUnitId = adUnitId;
var arParams = new LinearLayout.LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);
adView.LayoutParameters = arParams;
adView.LoadAd(new AdRequest.Builder().Build());
return adView;
}
protected override void OnElementChanged(ElementChangedEventArgs<AdControlView> e)
{
base.OnElementChanged(e);
if(Control == null)
{
CreateAdView();
SetNativeControl(adView);
}
}
}
}
In MainActivity, intialize MobileAds just before loading the app:
MobileAds.Initialize(ApplicationContext, "ca-app-pub-appid");
When I run, I get the red background but no ads are loaded. Any ideas?
In the AdControlView class, I added :
public static readonly BindableProperty AdUnitIdProperty = BindableProperty.Create("AdUnitId", typeof(string), typeof(AdControlView));
public string AdUnitId
{
get { return (string)GetValue(AdUnitIdProperty); }
set { SetValue(AdUnitIdProperty, value); }
}
Now I can see "Test Ad" in the banner placeholder.

How can i press a button in headerbar and do things in window in vala

How to make a button in headerbar and do things in window i've tried:
public class headerbar : Gtk.HeaderBar {
construct {
title = "Quiz";
subtitle = "You can solve this!";
show_close_button = true;
Gtk.Button button = new Gtk.Button.with_label ("Quit");
button.get_style_context ().add_class ("suggested-action");
button.set_valign (Gtk.Align.CENTER);
button.clicked.connect (() => {
var label = new Gtk.Label ("Hi");
main.add (label);
label.show ();
});
pack_start (button);
}
}
I got a sample as follow, hope it could help you:
public class AppTitleBar : Gtk.HeaderBar {
private Gtk.Button m_new_tab_button;
private Gtk.Box m_app_title_gui_box;
private Gtk.MenuButton m_main_menu_button;
public weak Workbench workbench { get; construct; }
public AppTitleBar (Workbench workbench) {
Object ( workbench: workbench );
}
construct {
set_show_close_button (true);
this.build_title_bar_layout();
}
public void add_new_tab(Widget title_widget)
{
m_app_title_gui_box.pack_start(title_widget);
title_widget.focus.connect(() => {
this.update_tab_inactive_all();
return true;
});
}
public void update_tab_inactive_all()
{
m_app_title_gui_box.foreach ((widget) => {
widget.set_opacity(0.3);
});
}
public void remove_tab_widget(Widget tab_bar)
{
m_app_title_gui_box.remove(tab_bar);
}
private void build_title_bar_layout()
{
m_main_menu_button = new Gtk.MenuButton ();
var menu_image = new Gtk.Image.from_icon_name ("open-menu-symbolic", Gtk.IconSize.BUTTON);
m_main_menu_button.set_image (menu_image);
m_main_menu_button.tooltip_text = ("Main Menu");
// create title bar box
m_app_title_gui_box = new Box(Orientation.HORIZONTAL, 2);
// create add new tab button
m_new_tab_button = new Gtk.Button.from_icon_name("list-add", Gtk.IconSize.BUTTON);
m_new_tab_button.get_style_context ().add_class ("back-button");
m_new_tab_button.valign = Gtk.Align.CENTER;
m_new_tab_button.always_show_image = true;
m_new_tab_button.can_focus = false;
m_new_tab_button.action_name = WorkbenchActions.ACTION_PREFIX + WorkbenchActions.ACTION_TAB_NEW;
m_new_tab_button.has_tooltip = true;
m_new_tab_button.tooltip_text = "Open a new connection (Ctrl+N)";
this.pack_end(m_main_menu_button);
this.pack_start(m_app_title_gui_box);
this.pack_start(m_new_tab_button);
}
}

Getting navigation bar height in dependency service - Xamarin Forms

i have this issue wherein i need to get the navigation bar height in my Dependency Service.
Currently I am stuck on what to follow here. I tried everything i find in stackoverflow and google but no one works for me.
Heres my code:
[assembly: Dependency(typeof(DeviceInfo))]
namespace Wicket.App.Mobile.iOS.Framework
{
public class DeviceInfo : IDeviceInfo
{
public float StatusBarHeight => (float)UIApplication.SharedApplication.StatusBarFrame.Size.Height;
public float NavigationBarHeight => GetNavigationBarHeight();
public static UINavigationController NavigationController { get; set; }
public float GetNavigationBarHeight()
{
//Get navigation bar height
return 0;
}
}
}
I already completed the android part and it works good. The only problem now is in iOS. I have tried getting the instance of navigationcontroller in AppDelegate so that I can just get the bar frame like this NavigationBar.Bounds.Height;
I think this should work:
var navheight = GetTopViewController().NavigationController.NavigationBar.Frame.Height;
public static UIViewController GetTopViewController()
{
var window = UIApplication.SharedApplication.KeyWindow;
var vc = window.RootViewController;
while (vc.PresentedViewController != null)
vc = vc.PresentedViewController;
if (vc is UINavigationController navController)
vc = navController.ViewControllers.Last();
return vc;
}
Solution:
How about pass an instance of viewController as parameter in the function inside the IDeviceInfo?
Try this:
public void getNaviHeight(ContentPage vc)
{
var renderer = Platform.GetRenderer(vc);
if (renderer == null)
{
renderer = RendererFactory.GetRenderer(vc);
Platform.SetRenderer(vc, renderer);
}
var viewController = renderer.ViewController;
var h = viewController.NavigationController?.NavigationBar.Frame.Height;
}
And use the dependency:
public MainPage ()
{
DependencyService.Get<IDeviceInfo>().getNaviHeight(this);
}
this worked to me:
var navigationBar = UIApplication.SharedApplication.KeyWindow.RootViewController.View.Subviews[0].Subviews.OfType<UINavigationBar>().FirstOrDefault();
if(navigationBar != null)
{
// continue here...
}

Add bluetooth-lowenergy services and writable characteristics to smartephone Xamarin

I am developing a mobile application that use bluetooth-lowenergy, i need to create services and characteristics in the application
Thanks
this after two days of search, and by reading this page BLE Android i solved my problem
here the class used to create services
using System;
using Android.App;
using Android.Bluetooth;
using Android.Bluetooth.LE;
using Android.OS;
using Java.Util;
using SitBle.Droid;
using SitBle.Interfaces;
using Exception = System.Exception;
[assembly: Xamarin.Forms.Dependency(typeof(Advertiser))]
namespace SitBle.Droid
{
public class Advertiser : IAdvertiser
{
private BluetoothAdvertiseCallback _advertiseCallback;
private readonly UUID _serviceUuid = UUID.FromString("795090c7-420d-4048-a24e-18e60180e23c");
private readonly UUID _characteristicCounterUuid = UUID.FromString("31517c58-66bf-470c-b662-e352a6c80cba");
private readonly UUID _characteristicInteractorUuid = UUID.FromString("0b89d2d4-0ea6-4141-86bb-0c5fb91ab14a");
private readonly UUID _descriptorConfigUuid = UUID.FromString("00002902-0000-1000-8000-00805f9b34fb");
public void Advertise()
{
try
{
_advertiseCallback = new BluetoothAdvertiseCallback();
var androidBluetoothGattServerCallback = new AndroidBluetoothGattServerCallback();
var adapter = BluetoothAdapter.DefaultAdapter;
var advertiseSettingBuilder = new AdvertiseSettings.Builder()
.SetAdvertiseMode(AdvertiseMode.Balanced).SetConnectable(true).SetTimeout(0)
.SetTxPowerLevel(AdvertiseTx.PowerMedium);
var advertiseSetting = advertiseSettingBuilder.Build();
var adverisingDataBuilder = new AdvertiseData.Builder().SetIncludeDeviceName(false).AddServiceUuid(new ParcelUuid(_serviceUuid));
adapter.BluetoothLeAdvertiser.StartAdvertising(advertiseSetting, adverisingDataBuilder.Build(), _advertiseCallback);
var appContext = Application.Context;
var mBluetoothManager = (BluetoothManager)appContext.GetSystemService("bluetooth");
var mGattServer = mBluetoothManager.OpenGattServer(appContext, androidBluetoothGattServerCallback);
mGattServer.AddService(CreateService());
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private BluetoothGattService CreateService()
{
BluetoothGattService service = new BluetoothGattService(_serviceUuid, GattServiceType.Primary);
// Counter characteristic (read-only, supports subscriptions)
BluetoothGattCharacteristic counter = new BluetoothGattCharacteristic(_characteristicCounterUuid,GattProperty.Read|GattProperty.Notify,GattPermission.Read);
BluetoothGattDescriptor counterConfig = new BluetoothGattDescriptor(_descriptorConfigUuid, GattDescriptorPermission.Read|GattDescriptorPermission.Write);
counter.AddDescriptor(counterConfig);
// Interactor characteristic
BluetoothGattCharacteristic interactor = new BluetoothGattCharacteristic(_characteristicInteractorUuid, GattProperty.Read|GattProperty.Write|GattProperty.Notify, GattPermission.Write);
service.AddCharacteristic(counter);
service.AddCharacteristic(interactor);
return service;
}
}
public class BluetoothAdvertiseCallback : AdvertiseCallback
{
public BluetoothAdvertiseCallback()
{
}
public override void OnStartSuccess(AdvertiseSettings settingsInEffect)
{
Console.WriteLine("Success");
}
public override void OnStartFailure(AdvertiseFailure errorCode)
{
Console.WriteLine("Fail");
}
}
public class AndroidBluetoothGattServerCallback : BluetoothGattServerCallback
{
public AndroidBluetoothGattServerCallback()
{
}
}
}

Caliburn.micro : Bind two views of ViewModel with tab Control

I am trying to bind two views of viewmodel to two tabs of tab control by editing sample source code Caliburn.Micro.SimpleMDI included with Caliburn.Micro source. This project contains ShellViewModel and TabViewModel with TabView. I added one View named TabViewDetails. I edited ShellViewModel as follows.
public class ShellViewModel : Conductor<IScreen>.Collection.OneActive
{
int count = 1;
public void OpenTab()
{
TabViewModel vm = null;
if (Items.Count != 0)
{
vm = new TabViewModel() { DisplayName = "Detail Tab " + count++ };
var secondView = new TabViewDetails();
ViewModelBinder.Bind(vm, secondView , null);
}
else
{
vm = new TabViewModel() { DisplayName = "Tab " + count++ };
}
ActivateItem(vm);
}
}
First tab is Ok. But the second tab shows nothing.Can anybody help to figure out the problem?.
I haven't used Caliburn.Micro much but the simple solution is one view, one view model. If you change your code to something like:
public class ShellViewModel : Conductor<IScreen>.Collection.OneActive {
int count = 1;
public void OpenTab()
{
Screen screen;
if (count != 0)
{
screen = new TabViewModel
{
DisplayName = "Tab " + _count++
};
}
else
{
screen = new TestViewModel
{
DisplayName = "Tab " + _count++
};
}
ActivateItem(screen);
}
}
where TestViewModel can be a TabViewModel
public class TestViewModel : TabViewModel
{
}
then this works ok.
The Caliburn docs does have a section multiple views over the same viewmodel but I haven't figured that out yet.

Resources