So i am using mvvmcross 6.2 and Xamarin Forms. I have setup the tabs using this informaiton Is there tabbed layout platform provided by mvvmcross?. I have an iOS app that works fine, When running the android app i get the following exception whenever initating one of the tasks.
Java.Lang.IllegalStateException: 'FragmentManager is already executing transactions'
The app is not busy while doing this so the busy indicator is not showing , however the app takes a very long time to change from login page to the tabs home. the exception does not seem to stop the process but it does really slow down the loading.
in my homeviemodel
public async Task ShowInitialViewModels()
{
tasks.Add(NavigationService.Navigate<tab1ViewModel>());
tasks.Add(NavigationService.Navigate<tab2ViewModel>());
tasks.Add(NavigationService.Navigate<tab3ViewModel>());
tasks.Add(NavigationService.Navigate<tabViewModel>());
await CheckFortab5ViewModel();
await Task.WhenAll(tasks);
}
in my home xaml
[XamlCompilation(XamlCompilationOptions.Compile)]
[MvxTabbedPagePresentation(TabbedPosition.Root, WrapInNavigationPage = true, Animated = false)]
public partial class HomePage : MvxTabbedPage<HomeViewModel>
{
in my tabs
[XamlCompilation(XamlCompilationOptions.Compile)]
[MvxTabbedPagePresentation(TabbedPosition.Tab, WrapInNavigationPage = false, NoHistory = true)]
public partial class tab1page: MvxContentPage<tab1ViewModel>
{
any ideas? should i even be worried about this?
Related
I am kind of new to Xamarin development. I tried to change the back button behavior with a binding command, but that didn't seem to work. This is the code for the view:
<Shell.BackButtonBehavior>
<BackButtonBehavior Command="{Binding GoBack}"/>
</Shell.BackButtonBehavior>
And this is the code for the view model:
public CreatePasswordVM()
{
_goBack = new Command(GoBackButton);
}
private ICommand _goBack;
public ICommand GoBack
{
get { return _goBack; }
}
public async void GoBackButton()
{
await Shell.Current.GoToAsync("../..");
}
When I pressed the back button, the method "GoBackButton" didn't call. I want to mention that on Android works.
Shell BackButtonBehavior command binding not working in UWP
Derive from Xamarin Form source code. BackButtonBehavior has not implemented for UWP platform, we could find Android and IOS implementation here and here. But for uwp there is not such tracker and there is not such value in the UWP ShellRenderer. For this scenario, we suggest your post new feature request in the Xamarin Forms github.
I have an application that I added a launch page to in the iOS and Android code. However when the app starts there is still quite a long delay while it fetches data. At this time there's a blank screen where I assume the app is still setting up the constructor.
I am trying to have an in-between page where that appears that loads the data. Not sure if this is the best way to do this but so far it's all that I have.
Here's the code that I have so far:
public App()
{
InitializeComponent;
MainPage = new NavigationPage(new Test.LoginPage())
{
};
}
My Test.LoginPage is a simple empty Xaml page with this C# back end:
public partial class LoginPage : ContentPage
{
public LoginPage()
{
InitializeComponent();
}
protected async override void OnAppearing()
{
await LongRunningTask();
App.MainPage = new AppShell(); // I want to start a shell app
}
}
public partial class AppShell : Shell
{
public AppShell()
{
Routing.RegisterRoute("HomeTab/QHPage", typeof(QHPage));
// etc
But the code has issues in that first of all I am not sure I am doing it correctly and secondly it says an object reference is required for App.MainPage.
Can anyone point me in the right direction and suggest how I could display this intermediate page and then display the real app pages?
Note that at some point I would also like to have a button on the login page that when clicked takes me to the app. But at this time I just want to get even the most simple version working so I am looking for some advice with that.
The easy way is to set the AppShell as MainPage. The code below works for me.
Application.Current.MainPage = new AppShell();
How can I present a modal view on iOS using MvvmCross?
Using Xamarin Studio on iOS and the MvvmCross NuGet version 4.2.2, none of the MvxModalSupportTouchViewPresenter, MvxModalNavSupportTouchViewPresenter or IMvxModalTouchView are even available.
Does the ViewModel even need to know about the fact that a particular view is presented as a modal view on iOS?
MvvmCross is a strong Page navigation framework. Default navigation using ShowViewModel<AViewModel> will use the stack metaphor: one on top of another on Android, slide atop each other on iOS, and use < on either platform to go back.
You can tell the ViewPresenter that a given view is modal by giving it a hint, in the form of an interface marker, by adopting IMvxModalIosView.
At the View Level
Adopt the IMvxModalIosView protocol:
public partial class AView : MvxViewController, IMvxModalIosView
At the AppDelegate Level
Replace var setup = new Setup(this, Window) by:
var presenter = new MvxModalSupportIosViewPresenter(this, Window);
var setup = new Setup(this, presenter);
setup.Initialize();
At the ViewModel Level
No change required. The ViewModel is actually not made aware of the modal presentation. Invoke:
ShowViewModel<AViewModel> // May be modal on certain platforms
To close a Page and go back to the previous one, regardless of your presentation style, use Close(this) on that very ViewModel. This will close a modal dialog, or pop a pushed view. A complete, bindable ICommand may look like this:
public ICommand BackCommand {
get { return new MvxCommand(() => Close(this)); }
}
Notes: In MvvmCross 4.2.2, Touch has been renamed iOS, so IMvxModalTouchView is now IMvxModalIosView. The new using are:
using MvvmCross.iOS.Platform;
using MvvmCross.iOS.Views.Presenters;
Using MvvmCross 5.5.2 all I had to get a modal was to add the following MvxModalPresentation attribute to my iOS view:
[Register("ExampleModalView")]
[MvxModalPresentation(
ModalPresentationStyle = UIModalPresentationStyle.PageSheet,
ModalTransitionStyle = UIModalTransitionStyle.CoverVertical
)]
public class ExampleModalView : MvxViewController
{
public ExampleModalView() {
}
...
}
Launching the modal is simple with the IMvxNavigationService service
await _navigationService.Navigate<ExampleModalViewModel>();
ExampleModalViewModel just needs to be a plain MvvmCross view model inheriting from MvxViewModel.
A useful reference for this is ModalView.cs in the iOS playground project: https://github.com/MvvmCross/MvvmCross/blob/develop/TestProjects/Playground/Playground.iOS/Views/ModalView.cs#L12
we were using the Notifier Plugin in our application to show the Notification for our Xamarin Forms application.
Notifier Plugin URL: https://github.com/edsnider/Xamarin.Plugins/tree/master/Notifier
For customizing the Notification Navigation with Android Platform,
Changes made in Plugin.LocalNotifications.Android Source as :
In LocalNotificationsImplementation as "var resultIntent = new Intent(Application.Context,typeof(RedirectActivity));"
In RedirectActivity Activity, we have included "MessagingCenter.Send("SampleAppNotificationNavigation", "RedirectToNavigationPage");"
Changes made in MyApplication.Android Source as :
In our Android application we subscribed messaging center as " MessagingCenter.Subscribe(this, "RedirectToNavigationPage", message =>
{
LoadApplication(new NextPage());
});"
Note: Based on the suggestion from Native to Forms Page Navigation we have implmented the same.
https://github.com/xamarin/xamarin-forms-samples/tree/master/Native2Forms
In our core project App page we have included as "
public class NextPage : Application
{
public NextPage()
{
MainPage = new NavigationPage(new ConfigureServer());
}
}"
Everything is working as expected (till ConfigureServer page constructor and intializecomponent() riased ) but failed to launch the ConfigureServer Page.
Kindly guide us to proceed further.
Thanks in advance.
I have 2 pages in my Xamarin Forms app. My first page has 4 icons in the toolbar. My second page is a login page and has a tick and a cross in the toolbar.
I can't get the login page to show any icons unless I make it a navigation page. I also have to clear ToolBarItems on the first page before calling PushAsync() otherwise it complains there are too many toolbar items.
If I call PopAsync() on the login page it does not return to the first page. I'm guessing this is due to their being 2 navigation pages. I also tried PopToRootAsync().The back button works however.
My question is - how do I show different toolbar icons on 2 different pages in a way that allows navigation to work?
I'm testing this on Windows Phone 8.0
Here is the code calling the login page:
private async void ShowLoginPage()
{
ToolbarItems.Clear();
var page = new NavigationPage(new LoginPage());
await Navigation.PushAsync(page);
}
and here is the code to return to the first page:
private void Cancel()
{
Navigation.PopToRootAsync();
}
I'm running Xamarin.Forms v1.2.2.6243
One thing you could try is to keep your Login Page inside of a NavigationPage, and then instead of running PopAsync() within the Login Page after they have logged in successfully, simply replace the MainPage with your old Navigation page:
In your App class:
public NavigationPage AppNavPage = new NavigationPage(new FirstPage());
public App() {
MainPage = AppNavPage;
}
In your FirstPage:
private async void ShowLoginPage() {
ToolbarItems.Clear();
var page = new NavigationPage(new LoginPage());
await Navigation.PushAsync(page);
}
In Login Page:
private async void OnCreateClicked(object sender, EventArgs e) {
bool loginInfoIsGood = CheckLoginInfo(); //Check their login info
if(loginInfoIsGood) {
Application.Current.MainPage = App.AppNavPage;
}
}
Otherwise, I have also done a custom renderer for the NavigationRenderer on iOS to insert toolbar items onto the right side of the Navigation Bar and have overridden some Menu related stuff on Android to change the icon text/colors.
One option that you have, and one that I implemented in my own app, is a custom renderer that removes the navigation header from the app and then you could build your own custom header. With this approach, you do lose some of the native feel of the app, and you have to implement much of the transitional functionality your self. However, it gives you alot more control over the look.
CustomRenderer that removes the navigationBar:
//add using statements
// add all view here that need this custom header, might be able to build a
//base page that others inherit from, so that this will work on all pages.
[assembly: ExportRenderer(typeof(yourView), typeof(HeaderRenderer))]
class HeaderRenderer : PageRenderer
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
this.NavigationController.SetNavigationBarHidden(true, true);
}
}
After this you can build a header view that can be placed on the top of every page (I am using xaml) so I don't know if it is relevant in you application.
Edit: You might need to change this renderer for differnt page types.