Searchbar in Navigation bar Or TabbedPage

GaganSinghGaganSingh USUniversity ✭✭✭

Hi, I was having trouble trying to get a searchbar inside the navigation bar. Then i read it wasn't possible because it only accepts ToolBarItems.
So now im trying to put the searchbar at the top of a tabbedpage where the navigation bar was. But it wont let me put anything other than a page in the TabbedPage.

<SearchBar Placeholder="Search"/>
<TabbedPage.Children>

    <custom:ContactsTab Title="Contacts" Icon="contacts_icon.png"/>
    <custom:ConversationsTab Title="Conversations" Icon="conversations_icon.png"/>

</TabbedPage.Children>

Posts

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    I had this problem not so long ago. You have 2 options.

    1. You go platform native and override the title or actionbar etc in each platform with a custom header.

    2. This would be the best approach as I had such a pain with the above method and for some reason this slipped my mind. Another programmer mentioned you can add a sub view into the NavigationPage. So I would create a NavigationPage, add in the Tabbed page to that, then add a view in the Navigation Page.

    I haven't done point 2 yet. I need to do it this week maybe, so I will write it up once I figure it out and confirm that it is possible.

  • GaganSinghGaganSingh USUniversity ✭✭✭

    I actually ended up just adding the search bar to a content page and then added the content page to the tabbedpage. That way i could still have other content inside the content page besides the search bar.

    <StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand"> <SearchBar x:Name="searchFor" Placeholder="Search" Text="{Binding Path=SearchText}" TextChanged="OnValueChanged" SearchButtonPressed="OnSearch" /> <StackLayout x:Name="segmentStax" Padding="10,5,10,10"/> </StackLayout>

  • BhaurajBiradarBhaurajBiradar USUniversity ✭✭

    I have the same problem. Above solution didn't worked for me, because I have 8 content pages inside tabbed page and I have to place Save and Submit button above tabbed tool bar. Is there any solution?

  • FifobuffersFifobuffers USMember

    @AdamP said:
    I had this problem not so long ago. You have 2 options.

    1. You go platform native and override the title or actionbar etc in each platform with a custom header.

    2. This would be the best approach as I had such a pain with the above method and for some reason this slipped my mind. Another programmer mentioned you can add a sub view into the NavigationPage. So I would create a NavigationPage, add in the Tabbed page to that, then add a view in the Navigation Page.

    I haven't done point 2 yet. I need to do it this week maybe, so I will write it up once I figure it out and confirm that it is possible.

    Point 2 is perfect, just tested on Android+iOS, thanks for the tip @AdamP

  • QwinQwin USUniversity ✭✭

    @Fifobuffers @AdamP hey guys just wondering but HOW do you add a subview to the NavigationPage.

  • codercamposcodercampos SVMember ✭✭

    @Qwin said:
    @Fifobuffers @AdamP hey guys just wondering but HOW do you add a subview to the NavigationPage.

    I think they were talking about: iOS side or NavigationPageRenderer

  • YuraBabiyYuraBabiy UAMember ✭✭✭

    @AdamP @Fifobuffers
    Could you please share your code of the second point?

  • iAlexeyiAlexey USMember
    edited January 2017
  • GaganSinghGaganSingh USUniversity ✭✭✭
    > @iAlexey said:
    > Brothers and sisters, that is the way to do it
    > http://stackoverflow.com/questions/27378981/how-to-use-searchview-in-toolbar-android

    The question is asking for Xamarin.Forms. Not Android.
  • Nobody to help about problem. I has error about topic in Xamarin Cross Platform too.

  • nattarSanthanarajnattarSanthanaraj USMember ✭✭

    Hi guys,
    I want the title in the Navigated page when the items clicked in the navigation drawer list. the page appears but there is no title. Please, any one helps me. thanks in advance

  • predalphapredalpha FRMember ✭✭

    @AdamP : Have you figured to insert layout on NavigationPage ? Still interested by the point 2 you mentionned.

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    @predalpha - coming back to this after a few years, but a TabbedPage, will be a root element, hence nothing can be inserted above it, except for the Navigation Bar.

    You can either create custom renderers for each platform's navigation bar and try to add or remove as necessary. A small example of a CR for NavigationBar, removing an icon (https://gist.github.com/Vaikesh/f86d1968c8166519f102)

    Or, use a CarouselView, as that can be placed inside a Page and you can have other views inserted above or below it.

  • predalphapredalpha FRMember ✭✭

    Thank you for your answer @AdamP

    Will try CustomRenderer solution even if i dont know how to add a template on the fly.
    Cause all the carouselview i have already tried contain an input bug overlay with the softkeyboard on UWP (phone / tablet)

  • kavya16kavya16 USMember ✭✭

    Hi All,

    Was anyone able to place SearchBar above and place the different tabbedpages below it in Xamarin.Forms?
    Please help.

    Thanks & Regards,
    Kavya

  • @Fifobuffers said:

    @AdamP said:
    I had this problem not so long ago. You have 2 options.

    1. You go platform native and override the title or actionbar etc in each platform with a custom header.

    2. This would be the best approach as I had such a pain with the above method and for some reason this slipped my mind. Another programmer mentioned you can add a sub view into the NavigationPage. So I would create a NavigationPage, add in the Tabbed page to that, then add a view in the Navigation Page.

    I haven't done point 2 yet. I need to do it this week maybe, so I will write it up once I figure it out and confirm that it is possible.

    Point 2 is perfect, just tested on Android+iOS, thanks for the tip @AdamP

    @Fifobuffers @AdamP It would be great help if you guys could share the code. I'm Stuck at a point where i want to have my default nav bar and then override it with 2 different nav bars one having search bar in it and other having custom buttons on it, all conditionally bind. how do i do this? i tried going by @AdamP 's second approach but i guess i messed up somewhere. @Fifobuffers can you please share how you got through it? Thanks

  • RCarvalhoRCarvalho PTMember ✭✭

    @adityadeshpande I found this one (https://www.linkedin.com/pulse/xamarin-forms-contentpage-searchbar-navigation-bar-vipin-mathews/), but this is only for Android using Xamarin.Forms, maybe give it a try and tell us some feedback :)

  • @RCarvalho said:
    @adityadeshpande I found this one but this is only for Android using Xamarin.Forms, maybe give it a try and tell us some feedback :)

    trying the same, but this needs too many changes (including Resource.Designer.cs) and still not working.
    also. i need 2 layouts that could be switched n top of default nav bar.
    and i don't understand how to achieve it by this approach.

  • @RCarvalho I worked more on that. that thing works for search bar.
    i'll write a blog about the extra things that i did to make it work. :)
    however i am unable to throw in my extra buttons in that nav bar. if you get a way around then please let me know
    thanks :#

  • RCarvalhoRCarvalho PTMember ✭✭

    @adityadeshpande well, i built that and figured that it only appears the search bar before API 22, did you find any solution for earlier API's?

  • @RCarvalho said:
    @adityadeshpande well, i built that and figured that it only appears the search bar before API 22, did you find any solution for earlier API's?

    No fortune so far, will surely revert back if i get to some solution or conclusion :smile:

  • JosueSamanoJosueSamano USMember ✭✭

    I'm using Prism.Unity.Forms
    How do I add my search icon to my navigation bar?

    My scenario is this:
    Login -> MasterDetail -> Categories (ListView and wanna my Search here)
    -> Employes (ListView and wanna my Search here)

    Categories is a ContentPage, it is not my root, my root is my MasterDetail, it displays a ContentPage of Categories, which has a list

    I have my Android and iOS projects

    Thanks

  • michaelitohmichaelitoh USMember ✭✭
    1. You go platform native and override the title or actionbar etc in each platform with a custom header.

    @AdamP Can you share this code?

  • RedoRedo IDMember ✭✭

    As per Xamarin Forms 3.2 in release version, you can use NavigationPage.TitleView

  • BrandonMinnickBrandonMinnick USXamarin Team Xamurai

    There's currently no way to do this in Xamarin.Forms, but we can create a custom renderer in both the Xamarin.iOS and Xamarin.Android to accomplish it.

    Here's a sample application for reference:
    https://github.com/brminnick/GitTrends

    And here's a blog post that shows how to add a search bar to a Xamarin.Forms app for both Xamarin.iOS & Xamarin.Android: https://www.codetraveler.io/2019/08/10/adding-a-search-bar-to-xamarin-forms-navigationpage/

    App.cs

    Use a Xamarin.Forms Platform-Specific to use LargeTitles on the Xamarin.iOS app.

    using Xamarin.Forms.PlatformConfiguration;
    using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
    
    public class App : Xamarin.Forms.Application
    {
        public App()
        {
            var navigationPage = new Xamarin.Forms.NavigationPage(new MyContentPage());
    
            navigationPage.On<iOS>().SetPrefersLargeTitles(true);
    
            MainPage = navigationPage;
        }
    }
    

    ISearchPage Interface

    Create an Interface that can be used across the Xamarin.Forms, Xamarin.Android and Xamarin.iOS projects.

    public interface ISearchPage
    {
        void OnSearchBarTextChanged(in string text);
        event EventHandler<string> SearchBarTextChanged;
    }
    

    Xamarin.Forms Page

    public class MyContentPage : ContentPage, ISearchPage
    {
        public MyContentPage()
        {
            SearchBarTextChanged += HandleSearchBarTextChanged
        }
    
        public event EventHandler<string> SearchBarTextChanged;
    
        public void OnSearchBarTextChanged(in string text) => SearchBarTextChanged?.Invoke(this, text);
    
        void HandleSearchBarTextChanged(object sender, string searchBarText)
        {
            //Logic to handle updated search bar text
        }     
    }
    

    iOS Custom Renderer

    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using UIKit;
    using MyNamespace;
    using MyNamespace.iOS;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.iOS;
    
    [assembly: ExportRenderer(typeof(MyContentPage), typeof(SearchPageRenderer))]
    namespace MyNamespace.iOS
    {
        public class SearchPageRenderer : PageRenderer, IUISearchResultsUpdating
        {
            bool _isFirstAppearing = true;
    
            public override void WillMoveToParentViewController(UIViewController parent)
            {
                base.WillMoveToParentViewController(parent);
    
                var searchController = new UISearchController(searchResultsController: null)
                {
                    SearchResultsUpdater = this,
                    DimsBackgroundDuringPresentation = false,
                    HidesNavigationBarDuringPresentation = false,
                    HidesBottomBarWhenPushed = true
                };
                searchController.SearchBar.Placeholder = string.Empty;
    
                parent.NavigationItem.SearchController = searchController;
    
                DefinesPresentationContext = true;
            }
    
            public override void ViewDidAppear(bool animated)
            {
                base.ViewDidAppear(animated);
    
                //Work-around to ensure the SearchController appears when the page first appears https://stackoverflow.com/a/46313164/5953643
                if (_isFirstAppearing)
                {
                    ParentViewController.NavigationItem.SearchController.Active = true;
                    ParentViewController.NavigationItem.SearchController.Active = false;
    
                    _isFirstAppearing = false;
                }
            }
    
            public void UpdateSearchResultsForSearchController(UISearchController searchController)
            {
                if (Element is ISearchPage searchPage)
                    searchPage.OnSearchBarTextChanged(searchController.SearchBar.Text);
            }
        }
    }
    

    Xamarin.Android Menu XML

    1. In the Xamarin.Android project, in the Resources folder, create a new folder called menu (if one doesn't already exist).

      • Note: the folder, menu, has a lowercase 'm'
    2. In the Resources > menu folder, create a new file called MainMenu.xml.

    enter image description here

    1. Open Resources > menu > MainMenu.xml

    2. In MainMenu.xml add the following code:

    <?xml version="1.0" encoding="utf-8" ?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto">
      <item android:id="@+id/ActionSearch"
            android:title="Filter"
            android:icon="@android:drawable/ic_menu_search"
            app:showAsAction="always|collapseActionView"
            app:actionViewClass="android.support.v7.widget.SearchView"/>
    </menu>
    

    Xamarin.Android CustomRenderer

    Uses the Plugin.CurrentActivity NuGet Package.

    using Android.Content;
    using Android.Runtime;
    using Android.Support.V7.Widget;
    using Android.Text;
    using Android.Views.InputMethods;
    using Plugin.CurrentActivity;
    using MyNamespace;
    using MyNamespace.Droid;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.Android;
    
    [assembly: ExportRenderer(typeof(MyContentPage), typeof(SearchPageRenderer))]
    namespace MyNamespace.Droid
    {
        public class SearchPageRenderer : PageRenderer
        {
            public SearchPageRenderer(Context context) : base(context)
            {
    
            }
    
            protected override void OnAttachedToWindow()
            {
                base.OnAttachedToWindow();
    
                if (Application.Current.MainPage is NavigationPage navigationPage)
                    navigationPage.Popped += HandleNavigationPagePopped;
    
                if (Element is ISearchPage && Element is Page page)
                    AddSearchToToolbar(page);
            }
    
            protected override void Dispose(bool disposing)
            {
                if (GetToolbar() is Toolbar toolBar)
                    toolBar.Menu?.RemoveItem(Resource.Menu.MainMenu);
    
                base.Dispose(disposing);
            }
    
            void AddSearchToToolbar(in Page page)
            {
                if (GetToolbar() is Toolbar toolBar
                    && toolBar.Menu?.FindItem(Resource.Id.ActionSearch)?.ActionView?.JavaCast<SearchView>().GetType() != typeof(SearchView))
                {
                    toolBar.Title = page.Title;
                    toolBar.InflateMenu(Resource.Menu.MainMenu);
    
                    if (toolBar.Menu?.FindItem(Resource.Id.ActionSearch)?.ActionView?.JavaCast<SearchView>() is SearchView searchView)
                    {
                        searchView.QueryTextChange += HandleQueryTextChange;
                        searchView.ImeOptions = (int)ImeAction.Search;
                        searchView.InputType = (int)InputTypes.TextVariationNormal;
                        searchView.MaxWidth = int.MaxValue; //Set to full width - http://stackoverflow.com/questions/31456102/searchview-doesnt-expand-full-width
                    }
                }
            }
    
            void HandleQueryTextChange(object sender, SearchView.QueryTextChangeEventArgs e)
            {
                if (Element is ISearchPage searchPage)
                    searchPage.OnSearchBarTextChanged(e.NewText);
    
            }
    
            void HandleNavigationPagePopped(object sender, NavigationEventArgs e)
            {
                if (sender is NavigationPage navigationPage
                    && navigationPage.CurrentPage is ISearchPage)
                {
                    AddSearchToToolbar(navigationPage.CurrentPage);
                }
            }
    
            Toolbar GetToolbar() => CrossCurrentActivity.Current.Activity.FindViewById<Toolbar>(Resource.Id.toolbar);
        }
    }
    

    Sample App

    Here's a sample app for reference:
    https://github.com/brminnick/GitTrends

    And a blog post that shows how to add a search bar for both Xamarin.iOS and Xamarin.Android: https://www.codetraveler.io/2019/08/10/adding-a-search-bar-to-xamarin-forms-navigationpage/

    iOS Gif

  • Hi BrandonMinnick. Thank you for the provided solution it works great. Only question I have is, can we redesign the layout for Android somehow? Instead of showing the icon next to title to be in a new row/under title (similar as iOS)?
    Thanks.

Sign In or Register to comment.