Xamarin AndroidX.Preferences - Cannot convert from 'SettingsFragment' to 'Android.Support.V4.App.Fragment' - c#

I'm trying to update the settings/preferences screen of my Xamarin Android app, which was using the PreferenceManager class. Since I'm targeting Android 10, this class is deprecated and I'd like to use the AndroidX.Preference library instead.
I followed Google's guide for making a settings screen with AndroidX. Here's the code I'm using
namespace SmartLyrics
{
[Activity(Label = "Settings", ConfigurationChanges = Android.Content.PM.ConfigChanges.ScreenSize | Android.Content.PM.ConfigChanges.Orientation, ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait)]
public class SettingsFragment : PreferenceFragmentCompat
{
public override void OnCreatePreferences(Bundle savedInstanceState, string rootKey)
{
AddPreferencesFromResource(Resource.Xml.perfs);
}
}
public class SettingsActivity : AppCompatActivity
{
protected override async void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.main_settings);
SupportFragmentManager
.BeginTransaction()
.Replace(Resource.Id.settingsContainer, new SettingsFragment()) //<--error here
.Commit();
}
}
}
I'm getting the error Cannot convert from 'SmartLyrics.SettingsFragment' to 'Android.Support.V4.App.Fragment'. I looked around online and couldn't find a workaround or anything about this error. I'd really like to use the AndroidX library to prevent any problems with unsupported code later on.
Any help is appreciated. Thanks!

Check which package AppCompatActivity refers to ?
If it:
using Android.Support.V7.App;
change it to :
using AndroidX.AppCompat.App;

Related

How to change Shell Tabbar height

My Problem:
I use Shell with bottom Tabbar and I simply want to change it height on Android and maybe on iOS.
My Search Results:
I know that the Tabbar is an Android/iOS build in feature with solid specified height.
There seems to be a way to achieve that using a "Custom-Renderer". All projects I have found with this approach don't work with my visual studio (>100 Errors or simply does nothing).
I find it hard to believe that i need >100 rows of code to "only" adjust a height. Could someone provide a working solution to change the Shell Tabbar (bottom tabs) height ?
Edit
Unfourtounately you need to create a custom renderer on each platform project:
Android
MyShellRenderer class
[assembly: ExportRenderer(typeof(App.AppShell), typeof(App.Droid.MyShellRenderer))]
namespace App.Droid
{
public class MyShellRenderer : ShellRenderer
{
public MyShellRenderer(Context context) : base(context)
{
}
protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
{
return new MyBottomNavViewAppearanceTracker(this, shellItem);
}
}
}
MyBottomNavViewAppearanceTracker class
class MyBottomNavViewAppearanceTracker : ShellBottomNavViewAppearanceTracker
{
public MyBottomNavViewAppearanceTracker(IShellContext shellContext, ShellItem shellItem) : base(shellContext, shellItem)
{
}
public override void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
{
bottomView.LayoutParameters.Height = 400;
base.SetAppearance(bottomView, appearance);
}
}
Edit:
iOS part credit goes to https://forums.xamarin.com/discussion/169894/how-to-change-shell-height-of-flyout-items-at-the-bottom-of-the-page
iOS
MyShellRenderer class
[assembly: ExportRenderer(typeof(App.AppShell), typeof(App.iOS.MyShellRenderer))]
namespace App.iOS
{
public class MyShellRenderer : ShellRenderer
{
protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
{
return new MyCreateTabBarAppearanceTracker();
}
}
}
CreateTabBarAppearanceTracker class
class CreateTabBarAppearanceTracker : ShellTabBarAppearanceTracker
{
public override void SetAppearance(UITabBarController controller, ShellAppearance appearance)
{
UITabBar tabBar = controller.TabBar;
int tabBarHeight = 100;
if (tabBar.Frame.Height != tabBarHeight)
{
tabBar.Frame = new CGRect(tabBar.Frame.X, tabBar.Frame.Y + (tabBar.Frame.Height - tabBarHeight), tabBar.Frame.Width, tabBarHeight);
}
}
}
Extras
You were probably missing some namespaces that would explains the abnormal big number of errors.
could not be found are you missing a using directive or an assembly reference
Usually people don't include namespaces (using statements) in answers because most of the time namespaces are obvious and are handled easily by visual studio intellisense.
Just put or hover the cursor on the red underlined statement and a small tooltip appears
Then click on "Show potential fix" or one of the keyboard shortcuts, select the appropriate fix (usually the first one of the suggested list), in this case intelisense will add the required namespace automatically.
Every Code example i have found has excluded the using directives. in my case i needed those following 3 which i wasnt able to find. Thanks to the answer of #Cfun the code above work with adding:
using Google.Android.Material.BottomNavigation;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

How can I change style of the original tabbed page bar (android with xamarin.forms)?

good morning,
I'm designing my first app in xamarin.forms, but I ran into a problem that is the style of the tabbedpage bar in android.
On iOS it works great, but on Android it has a different display, but I would like to make the homogeneous thing on both operating systems know how to do it?
Screen Android https://ibb.co/cYRLvc4
Screen iOS https://ibb.co/ysnxBr8
You should use a custom effect, first update your android target to 9.0 (and support libraries)
then, create the Routing Effect in your Forms solution:
using Xamarin.Forms;
namespace YourApp
{
public class NoShiftEffect : RoutingEffect
{
public NoShiftEffect() : base("MyEffect.NoShiftEffect")
{
}
}
}
Then, in Android, create a custom renderer:
using Android.Support.Design.BottomNavigation;
using Android.Support.Design.Widget;
using Android.Views;
using yournamespace.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly:ResolutionGroupName ("MyEffect")]
[assembly:ExportEffect (typeof(NoShiftEffect), "NoShiftEffect")]
namespace yournamespace.Droid
{
public class NoShiftEffect : PlatformEffect
{
protected override void OnAttached ()
{
if (!(Container.GetChildAt(0) is ViewGroup layout))
return;
if (!(layout.GetChildAt(1) is BottomNavigationView bottomNavigationView))
return;
// This is what we set to adjust if the shifting happens
bottomNavigationView.LabelVisibilityMode = LabelVisibilityMode.LabelVisibilityLabeled;
}
protected override void OnDetached ()
{
}
}
}
finally, in your tabbde page:
<TabbedPage.Effects>
<local:NoShiftEffect />
</TabbedPage.Effects>

How is Setup class instantiated in MVVMCross in Xamarin?

I'm starting learning MVVM cross, In the android app, I have a splash screen class:
[Activity(MainLauncher = true,
Label = "#string/app_name",
Theme = "#style/Theme.Splash",
NoHistory = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,
ScreenOrientation = ScreenOrientation.Portrait)]
public class SplashScreen : MvxSplashScreenActivity
{
public SplashScreen() : base(Resource.Layout.SplashScreen)
{
}
}
and this is the Setup class:
public class Setup : MvxAndroidSetup
{
protected Setup(Context applicationContext) : base(applicationContext)
{
}
protected override IMvxApplication CreateApp()
{
return null;
}
}
the problem is that the debugger doesn't hit the constructor of the Setup Class, instead I get "An unhandled exception" after the constructor of the splash screen
EDIT
I've already defined the App class in the PCL project:
public class App : MvxApplication
{
public override void Initialize()
{
base.Initialize();
}
also defined the AppStart:
public class AppStart : MvxNavigatingObject, IMvxAppStart
{
public async void Start(object hint = null)
{
//hardcoded login for this demo
//var userService = Mvx.Resolve<IUserDataService>();
//await userService.Login("gillcleeren", "123456");
ShowViewModel<MainViewModel>();
}
}
The main reason behind this project is to understand the sequence of code required and executed by MVVM Cross, so I provide the minimum code till it runs successfully without runtime errors.
Update
I have read your code again more thoroughly and I can see the issue now. You defined the constructor of the Setup class as protected, which makes it invisible for activation.
On MvvmCross for Android the magic happens inside MvxAndroidSetupSingleton class (see the source code here) which searches for the Setup type you defined. The FindSetupType method looks for your defined Setup class first and then inside the CreateSetup method Activator.CreateInstance is used to build the Setup instance. The CreateInstance method variant used however searches only for public constructors, which means it doesn't find your protected one. The result is that it cannot build the Setup class and crashes.
Original answer
The reason this happens is that you have no Core libary that would define the MvvmCross App class and would initialize other required setup. I suggest you to start with a simple tutorial or to look into the official sample projects to see what is necessary to make MvvmCross work in a Xamarin.Android app.

Xamarin Activity vs Application

Whats the difference b/w using Activity vs Application in Xamarin? Why would one want to use one approach over another?
For example, when I create a new Xamarin Form project in VS I get the follow:
[Activity(Label = "eApprove Main Activity", MainLauncher = true, Icon = "#drawable/eA_icon")]
public class MainActivity : Activity
{
...
}
I have also seen examples on internet where people are using Application class as their main Entry point:
namespace MyExpenses.Android
{
[Application(Theme = "#android:style/Theme.Holo.Light") ]
public class MyExpensesApplication : Application
{
public static Activity CurrentActivity { get; set; }
public MyExpensesApplication(IntPtr handle, global::Android.Runtime.JniHandleOwnership transer)
:base(handle, transer)
{
}
public override void OnCreate()
{
base.OnCreate();
}
}
}
Please make sure you do not confuse a classical Xamarin.Android app with the android portion of a Xamarin.Forms app. My quick and easy answer/recommendation would be that you would have one Application class per App project per platform and as many Activities as you like. The application is your entry point that kicks of any numbers activities based on your needs...

c# An object reference is required for the nonstatic field, method, or property Android.Widget.TabHost.NewTabSpec(string)

I'm trying ot create an app which should include some tabs for navigation and I followed a walkthrough, adding my own details, but I get one error twice in the final step.
The walkthrough I used was this: http://developer.xamarin.com/guides/android/user_interface/tab_layout/Walkthrough_Creating_a_tabbed_ui/
I didn't use the walkthrough project, but started my own project.
The errors appear in line 31 and 36.
Also, I'm very much a beginner at this.
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
namespace AppTest1
{
[Activity (Label = "Pathfinder Combat Companion", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
CreateTab(typeof(Combat_Statistics), "combat_stats", "Combat Statistics", Resource.Drawable.ic_tab_whats_on);
CreateTab(typeof(ConditionsBuffs), "condi_buffs", "Consitions/Buffs", Resource.Drawable.ic_tab_speakers);
CreateTab(typeof(Skills), "skills", "Skills", Resource.Drawable.ic_tab_sessions);
CreateTab(typeof(Spellbook), "spellbook", "Spellbook", Resource.Drawable.ic_tab_my_schedule);
}
private void CreateTab(Type activityType, string tag, string label, int drawableId )
{
var intent = new Intent(this, activityType);
intent.AddFlags(ActivityFlags.NewTask);
var spec = TabHost.NewTabSpec(tag);
var drawableIcon = Resources.GetDrawable(drawableId);
spec.SetIndicator(label, drawableIcon);
spec.SetContent(intent);
TabHost.AddTab(spec);
}
}
}
I didn't use the walkthrough project, but started my own project.
Then carefully look at the differences.
You're inheriting from Activity, which doesn't have a TabHost property.
TabActivity does, so change your class to public class MainActivity : TabActivity. Or instantiate a TabHost yourself (if the API supports that).

Categories

Resources