rid00z / FreshMvvm

FreshMvvm is a super light Mvvm Framework designed specifically for Xamarin.Forms. It's designed to be Easy, Simple and Flexible.
Apache License 2.0
594 stars 173 forks source link

2.2.3 SwitchSelectedMaster doesnt work in Android #188

Open EmilAlipiev opened 6 years ago

EmilAlipiev commented 6 years ago

Hi,

this function seems that it doesnt work anymore with the newest release

await CoreMethods.SwitchSelectedMaster<MainPageModel>();

I have just double checked and it works fine in 2.2.0 2.2.2 is also not working. 2.2.1 I dont know. I cant install because of dependencies.

EmilAlipiev commented 6 years ago

@rid00z Have you seen this issue please? It should be a small glitch, I appreciate if you can look into it. It holds us to use latest version. thank you

EmilAlipiev commented 6 years ago

@rid00z have you had any change to check that issue? If you need a repro please let me know but I think that it is a general issue with the version greater than 2.2.0

EmilAlipiev commented 6 years ago

@rid00z I have downloaded sample and debugged. it is working fine when using FreshMasterDetailNavigationContainer but if I use ThemedMasterDetailNavigationContainer as you suggested earlier. this is not working any longer. it used to work for 2.2.0. please find the repro project.

FreshMvvm-master.zip

EmilAlipiev commented 6 years ago

Ok For anyone who is looking for a solution here. Freshmvvm solution is incomplete and commit referenced made it even worse. It forces us to use only text in masterdetailpage but when you try to use icons with a themed solution as @rid00z advised in other issue here, this fails to work on SwitchSelectedMaster. Instead temprarily I copied entire FreshMasterDetailNavigationContaner and changed in my project as below. We need fresh mvvm to have this as extra or replacing existing solution for people who wants to use custom listview template


 [Runtime.Preserve(AllMembers = true)]
    public class ThemedMasterDetailNavigationContainer : Xamarin.Forms.MasterDetailPage, IFreshNavigationService
    {
        //public static readonly BindableProperty ItemTemplateSelctorProperty =
        //   BindableProperty.Create(nameof(MenuItemItemTemplate), typeof(DataTemplate), typeof(StyledMDContainer), default(DataTemplate));

        public ListView _listView { get; set; }
        List<Page> _pagesInner = new List<Page>();
        public string NavigationServiceName { get; private set; }

        List<MenuItem> pageIcons = new List<MenuItem>();

        Dictionary<string, Page> _pages = new Dictionary<string, Page>();
        public Dictionary<string, Page> Pages { get { return _pages; } }

        ObservableCollection<string> _pageNames = new ObservableCollection<string>();
        protected ObservableCollection<string> PageNames { get { return _pageNames; } }

        public void AddPageWithIcon<T>(string title, string icon = "", object data = null, string detail = null) where T : FreshBasePageModel
        {
            AddPage<T>(title, data);
            pageIcons.Add(new MenuItem
            {
                Title = title,
                IconSource = icon,
                Detail = detail
            });
        }
        public ThemedMasterDetailNavigationContainer() : this(Constants.DefaultNavigationServiceName)
        {
        }

        public ThemedMasterDetailNavigationContainer(string navigationServiceName)
        {
            NavigationServiceName = navigationServiceName;
            RegisterNavigation();
        }

        public void Init(string menuTitle, string menuIcon = null)
        {
            CreateMenuPage(menuTitle, menuIcon);
            RegisterNavigation();
        }

        protected virtual void RegisterNavigation()
        {
            FreshIOC.Container.Register<IFreshNavigationService>(this, NavigationServiceName);
        }

        public void AddPage<T>(string title, object data = null) where T : FreshBasePageModel
        {
            var page = FreshPageModelResolver.ResolvePageModel<T>(data);
            page.GetModel().CurrentNavigationServiceName = NavigationServiceName;
            _pagesInner.Add(page);
            var navigationContainer = CreateContainerPage(page);
            _pages.Add(title, navigationContainer);
            _pageNames.Add(title);
            if (_pages.Count == 1)
                Detail = navigationContainer;
        }

        protected void CreateMenuPage(string menuPageTitle, string menuIcon = null)
        {
            _listView = new ListView();

            _listView.SeparatorVisibility = SeparatorVisibility.Default;
            _listView.SeparatorColor = Color.White;
            var _menuPage = new ContentPage();
            _menuPage.Title = menuPageTitle;
            _menuPage.BackgroundColor = Color.FromHex("#c8c8c8");

            _listView.ItemsSource = pageIcons;

            var cell = new DataTemplate(typeof(CustomCell));
            //var footer = new DataTemplate(typeof(MasterPageFooter));
            //       var cell = new DataTemplate(typeof(ImageCell));
            //cell.SetValue(TextCell.TextColorProperty, Color.Black);
            //cell.SetBinding(ImageCell.TextProperty, "Title");
            //cell.SetBinding(ImageCell.ImageSourceProperty, "IconSource");

            //listview.FooterTemplate = footer;
            _listView.ItemTemplate = cell;
            _listView.ItemSelected += (sender, args) =>
            {
                if (Pages.ContainsKey(((MenuItem)args.SelectedItem).Title))
                {
                    Detail = Pages[((MenuItem)args.SelectedItem).Title];
                }
                IsPresented = false;
            };

            _menuPage.Content = _listView;

            var navPage = new NavigationPage(_menuPage) { Title = "Menu" };

            if (!string.IsNullOrEmpty(menuIcon))
                navPage.Icon = menuIcon;

            Master = navPage;

        }

        internal Page CreateContainerPageSafe(Page page)
        {
            if (page is NavigationPage || page is MasterDetailPage || page is TabbedPage)
                return page;

            return CreateContainerPage(page);
        }

        protected Page CreateContainerPage(Page page)
        {
            var navigation = new NavigationPage(page);
            navigation.BarTextColor = Color.White;

            return navigation;
        }

        public Task PushPage(Page page, FreshBasePageModel model, bool modal = false, bool animate = true)
        {
            if (modal)
                return Navigation.PushModalAsync(CreateContainerPageSafe(page));
            return (Detail as NavigationPage).PushAsync(page, animate); //TODO: make this better
        }

        public Task PopPage(bool modal = false, bool animate = true)
        {
            if (modal)
                return Navigation.PopModalAsync(animate);
            return (Detail as NavigationPage).PopAsync(animate); //TODO: make this better            
        }

        public Task PopToRoot(bool animate = true)
        {
            return (Detail as NavigationPage).PopToRootAsync(animate);
        }

        public void NotifyChildrenPageWasPopped()
        {
            if (Master is NavigationPage)
                ((NavigationPage)Master).NotifyAllChildrenPopped();
            if (Master is IFreshNavigationService)
                ((IFreshNavigationService)Master).NotifyChildrenPageWasPopped();

            foreach (var page in this.Pages.Values)
            {
                if (page is NavigationPage)
                    ((NavigationPage)page).NotifyAllChildrenPopped();
                if (page is IFreshNavigationService)
                    ((IFreshNavigationService)page).NotifyChildrenPageWasPopped();
            }
            if (this.Pages != null && !this.Pages.ContainsValue(Detail) && Detail is NavigationPage)
                ((NavigationPage)Detail).NotifyAllChildrenPopped();
            if (this.Pages != null && !this.Pages.ContainsValue(Detail) && Detail is IFreshNavigationService)
                ((IFreshNavigationService)Detail).NotifyChildrenPageWasPopped();
        }

        public Task<FreshBasePageModel> SwitchSelectedRootPageModel<T>() where T : FreshBasePageModel
        {
            var tabIndex = _pagesInner.FindIndex(o => o.GetModel().GetType().FullName == typeof(T).FullName);

            _listView.SelectedItem = pageIcons[tabIndex];

            return Task.FromResult((Detail as NavigationPage).CurrentPage.GetModel());
        }

    }

    [Runtime.Preserve(AllMembers = true)]
    public class MenuItem
    {
        public string Title { get; set; }
        public string IconSource { get; set; }
        public string Detail { get; set; }
    }
    [Runtime.Preserve(AllMembers = true)]
    public class CustomCell : ViewCell
    {
        public CustomCell()
        {
            View = new MasterPageViewCell();
        }
    }
codegrue commented 6 years ago

You can definitly have a custom menu (master) page using FreshMvvm like this:

var masterdetail = new FreshMasterDetailNavigationContainer();
masterdetail.Master = FreshPageModelResolver.ResolvePageModel<MenuViewModel>();  
masterdetail.Detail = FreshPageModelResolver.ResolvePageModel<ContentViewModel>();  
EmilAlipiev commented 5 years ago

@codegrue sorry replying so late. i have just recognized your comment. my solution is already using Freshmvvm as you can see it implements IFreshNavigationService but instead of sticking with default FreshMasterDetailNavigationContainer. I have created a custom solution where you are more flexible and you can do whatever you want. this was adivsed by owner of this project in one of the issues.