I am new to Sencha Touch development and trying to develope an app using it. I have been reading its docs and examples. I would like to know what is a best approach to start an app based on following scenario.
LoginView to start the app and then a navigation view.
I am struggling to figure out whether to use NavigationView or Card(for login) + Navigation View(for rest) or any other approach.
If i start with NavigationView then back button appears on top which i don't want to show on second view. dont know how to hide it so can i use something like Card(for login) + Navigation View.
Help is appreciated.
Create a login view.
Do your ajax request from your login view.
If successful login then you can do something like this:
Ext.Viewport.animateActiveItem(Ext.Viewport.getComponent('mainPanel'), { type: 'slide'});
That will animate your mainPanel and slide it into the view. Assuming your 'mainPanel' is your navigation view. The navigation view will start at its default position with no back button. You can now push views into your navigation view.
From a controller:
config: {
refs: {
mainPanel: 'main'
},
control: {
"list": {
itemtap: 'onListItemTap'
}
}
},
onListItemTap: function(dataview, index, target, record, e, options) {
var myNewView = Ext.create('MyApp.view.Testview');
this.getMainPanel().push(myNewView);
}
Later, if you need to, you can switch back to your login view at any time:
Ext.Viewport.setActiveItem(0);
or
Ext.Viewport.setActiveItem(Ext.Viewport.getComponent('MyLoginpanel'))
Related
I am building an app that makes use of some App links. In below example, I want to open a ResetPasswordPage when the user activates a link from an e-mail.
protected override async void OnInitialized()
{
InitializeComponent();
await NavigationService.NavigateAsync("/NavigationPage/LoginPage");
}
protected override void OnAppLinkRequestReceived(Uri uri)
{
if (uri.Host.EndsWith("site.nl", StringComparison.OrdinalIgnoreCase))
{
if (uri.AbsolutePath.StartsWith(#"/appname/resetpassword/"))
{
if (uri.Segments.Length == 4)
{
string resetCode = uri.Segments[3];
NavigationParameters param = new();
param.Add(NavConst.PasswordResetCode, resetCode);
await NavigationService.NavigateAsync("ResetPasswordPage", param);
}
}
}
}
This code works, but not what I would expect (for both iOS and Android). I would expect that ResetPasswordPage would be added to the navigation stack that was set in OnInitialized, so that it would contain a back button in the navigation bar, bringing the user back to the login page in this case.
But instead, it looks like the navigation stack gets replaced. When ResetPasswordPage is shown, and the user clicks the hardware back button, the app is closed. However, i want it to go back to where the user was before.
Am I not understanding some navigation concepts well or might this be a bug?
The NavigationService is a rather unique service within Prism for Xamarin.Forms. It is constructed new for each page as navigation and the navigation stack is dependent on where you are navigating from.
For instance when you Navigate from the context of a MasterDetailPage / FlyoutPage, it understands that you aren't trying to push a modal on top of that page but instead you are starting from the context of Detail/Flyout. If the NavigationService continually updated the Page context then the navigation service injected into that MasterDetailPage/FlyoutPage's ViewModel would have no idea that it needed that page as the context to navigate from.
Your issue here ultimately is that you are Navigating from the context of the Application which has a NavigationService with no Page set. As a result even a relative Navigation will still have the effect of an absolute Navigation thus resetting the Application.MainPage since that NavigationService does not have the contextual understanding of another page.
Depending on your business requirements you have a few different options. One is to do an absolute Navigation that gives you navigation stack that you're looking for.
Optionally you may want to get the currently displayed page and update the NavigationService to understand it. In the App class you might add something like:
protected override void OnAppLinkRequestReceived(Uri uri)
{
if (NavigationService is IPageAware pa)
{
page.Page = PageUtilities.GetCurrentPage(MainPage);
}
if (someCondition)
{
// This will now navigate from relatively from the page
// returned by GetCurrentPage.
NavigationService.NavigateAsync("SomeRelativeUrl")
.OnNavigationError(HandleNavigationError);
}
}
I meet a scenario to navigate from MyTabbedPage/ChildTabPage1/Page1 to MyTabbedPage/ChildTabPage2/Page2 in Xamarin.Forms
Right now, I can only switch between MyTabbedPage/ChildTabPage1 and MyTabbedPage/ChildTabPage2. But I need to navigate directly from MyTabbedPage/ChildTabPage1/Page1 to MyTabbedPage/ChildTabPage2/Page2
How to achieve this?
Thank you very much in advance for your helps.
You can try something like this.
public App()
{
InitializeComponent();
var parentPage = new MasterDetailView(); // name of the master detail page
parentPage.IsPresented = false;
var tabbedPage = new MasterDetailTabbedPage(); // name of the tabbed page
tabbedPage.CurrentPage = tabbedPage.Children[2]; // specify the index of the tab
parentPage.Detail = new NavigationPage(tabbedPage); // assign the tabbed page to master detail page
MainPage = parentPage; // navigate to master detail page (3rd tab selected)
}
If you want to navigate MyTabbedPage/ChildTabPage1/Page1 to MyTabbedPage/ChildTabPage2/Page2 in Xamarin.Forms, I suggest you can consider to use Shell to do this.
Xamarin.Forms Shell includes a URI-based navigation experience that uses routes to navigate to any page in the application, without having to follow a set navigation hierarchy. In addition, it also provides the ability to navigate backwards without having to visit all of the pages on the navigation stack.
Here is the article about using Shell:https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/navigation
I need to have something like that with XF Tabbed Page:
I.e., I need some panel which would appear over the whole content (including any tabs) where I can add some custom content. (The reason why I am asking it here, as it wouldn't be an issue in case of common simple page, when I would just have some overlapping view placed on the page).
In functionality it should be something like Action Sheets, but be cross-platform (i.e., defined as common XF view) and include custom content.
But it must be not necessary custom renderers with actually Action Sheet implementation (and AlertDialog accordingly to this). It would be perfect to have some view placed somewhere (I don't know where) in the page layout structure to achieve this.
Or Action Sheet and AlertDialog (with custom renderers) are still the easiest way to have it these days in XF? Thanks!
You can use ACR User Dialogs, and you can specify the UseBottomSheet option to make the action sheet appear at the bottom. Its available as a NuGet package, so there is no need for any custom renderers.
Acr.UserDialogs.ActionSheetConfig = new Acr.UserDialogs.ActionSheetConfig();
config.UseBottomSheet = true;
config.Title = "My Options";
config.Add(
"Option 1",
() =>
{
Device.BeginInvokeOnMainThread(async () => {
await DisplayAlert("", "Clicked option 1", "OK");
});
},
null);
config.Cancel = new Acr.UserDialogs.ActionSheetOption("Cancel");
And to display it:
Acr.UserDialogs.UserDialogs.Instance.ActionSheet(config);
I am trying to implement a login scenario with Xamarin Forms and Prism.
My application root page is a MasterDetail page (HomeMasterDetailPage); this being used to provide the side menu.
What I am trying to do is to have the HomeMasterDetailPage page shown with Content set to an instance of LoginPage. When the user logs in, the Content should change to an instance of HomeDetailContentPage. It should not be possible to return to the LoginPage using the back button.
I am using the NavigationService from Prism Forms.
My start up is like this...
public partial class App : PrismApplication {
public App(IPlatformInitializer initializer = null)
: base(initializer) {
}
protected override void OnInitialized() {
InitializeComponent();
Uri uri = new Uri($"/{nameof(NavigationPage)}/{nameof(HomeMasterDetailPage)}/{nameof(HomeDetailContentPage)}", UriKind.Absolute);
var settings = Container.Resolve<SettingsService>();
if (!settings.DeviceUserID.HasValue)
uri = new Uri($"/{nameof(NavigationPage)}/{nameof(HomeMasterDetailPage)}/{nameof(LoginPage)}", UriKind.Absolute);
NavigationService.NavigateAsync(uri);
}
protected override void RegisterTypes() {
Container.RegisterTypeForNavigation<NavigationPage>();
Container.RegisterTypeForNavigation<LoginPage, LoginPageViewModel>();
Container.RegisterTypeForNavigation<HomeMasterDetailPage, HomePageViewModel>();
Container.RegisterTypeForNavigation<HomeMasterContentPage>();
Container.RegisterTypeForNavigation<HomeDetailContentPage>();
}
}
This correctly displays the LoginPage within the HomeMasterDetailPage if the user is not already logged on, and the HomeDetailContentPage within the same HomeMasterDetailPage if the user is logged on.
The problem comes when actually logging on; the following is the code within the view model for the LoginPage...
protected async Task ExecuteLoginCommand() {
Uri uri = new Uri($"/{nameof(NavigationPage)}/{nameof(HomeMasterDetailPage)}/{nameof(HomeDetailContentPage)}", UriKind.Absolute);
await this.navigationService.NavigateAsync(uri);
}
It is my understanding that by using an absolute Uri this should reset the navigation so that the new page arrangement (/NavigationPage/HomeMasterDetailPage/HomeDetailContentPage) is at the top and bottom of the stack, allowing me to then move forward from there. Instead, I am getting an unhandled exception (on Android 7.0).
What am I doing wrong?
Note: All of the examples that I see have the MasterDetailPage at the root with Content being set to NavigationPage/ContentPage; when I try this I do not get exceptions, however the side menu operates differently within the MasterDetailPage - when you tap on the "hamburger" the side menu slides in over everything (including the action/title bar) and the only way to clear it is to tap outside of the side menu that slides in whereas when I show the MasterDetailPage within a NavigationPage the side menu slides in below the action/title bar and the hamburger changes to an arrow that you can click to hide the side menu again.
I can't say I've tested this exact scenario. However, if your LoginPage is the Detail of a MasterDetailPage, you may not want to perform the navigation from the LoginPage. You could, instead create a SuccessfulLoginEvent, which you would then publish from the LoginPage using the IEventAggregator, and you would subscribe to on your MasterDetailPage's ViewModel. You could then perform the navigation as _navigationService.NavigateAsync("NavigationPage/ViewA") and it should reset the Detail such that the back button doesn't bring you to the LoginPage.
Alternatively, you can simply perform an absolute Navigation which has the effect of:
Application.Current.MainPage = new MyPage().
To do to this, you could do the navigation from anywhere as:
_navigationService.NavigateAsync("/MyMasterDetailPage/NavigationPage/ViewA")
I am creating an app using Xamarin Forms. I have a MainTab page that displays all the 4 tabs. There is one specific tab call Me tab.
As of now the Me Tab displays the user's profile. However, when the user is not logged in, it my UserLogin page should be displayed instead. How do I do that in Xamarin forms?
You can achieve this in various ways. If you're using a MVVM approach the most straight forward solution would be to set a binding in your viewmodel indicating user logging. Based on that you can set your
tabbedPage.CurrentPage = TheTabPageYouWant.
If you're using codebehind, just use in your ;
public bool UserLogged
{
get { return _userLogged; }
set
{
_userLogged = value;
if (_userLogged)
{
tabbedPage.CurrentPage = UserProfilePage.
return;
}
tabbedPage.CurrentPage = LogInPage.
}
I strongly recommend any Xamarin.Forms book and MVVM techniques for you.
Don't hesitate to ask any further questions.