2

I am using masterdetail page within this page i am using tabbed page now i want to show toolbar icon and search bar on the top of page.i am able to place toolbar icon but struggling with search bar.how to place it at the top its behavior should match with the search bar in whatsapp app and in youtube app

priya_d
  • 393
  • 4
  • 24

5 Answers5

2

The WhatsApp search bar is just that, a SearchBar control which you can add to your XAML layout as follows:

<StackLayout>
    <SearchBar Placeholder="Search" Text="{Binding Filter}" />
    <ListView ItemSource="{Binding Items}">
        ...
    </ListView>
</StackLayout>

Ensure you have a backing property for the filter. You can use the setter of this property to intercept people filtering the data and filter the Items property accordingly.

The YouTube search behaves a bit differently. The toolbar item pops a new screen modally where the search is handled similar to a UISearchController (on iOS). There is no Xamarin Forms drop-in control (that I'm aware of) that does this for you so you'll probably have to roll your own.

Steven Thewissen
  • 2,971
  • 17
  • 23
1

We can create a custom renderer on both 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
    {
        readonly UISearchController _searchController;

        public SearchPageRenderer()
        {
            _searchController = new UISearchController(searchResultsController: null)
            {
                SearchResultsUpdater = this,
                DimsBackgroundDuringPresentation = false,
                HidesNavigationBarDuringPresentation = false,
                HidesBottomBarWhenPushed = true
            };
            _searchController.SearchBar.Placeholder = string.Empty;
        }

        public override void ViewDidAppear(bool animated)
        {
            base.ViewDidAppear(animated);

            if (ParentViewController.NavigationItem.SearchController is null)
            {
                ParentViewController.NavigationItem.SearchController = _searchController;
                DefinesPresentationContext = true;

                //Work-around to ensure the SearchController appears when the page first appears https://stackoverflow.com/a/46313164/5953643
                ParentViewController.NavigationItem.SearchController.Active = true;
                ParentViewController.NavigationItem.SearchController.Active = false;
            }
        }

        public override void ViewWillDisappear(bool animated)
        {
            base.ViewWillDisappear(animated);

            ParentViewController.NavigationItem.SearchController = null;
        }

        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 (Element is ISearchPage && Element is Page page && page.Parent is NavigationPage navigationPage)
            {
                //Workaround to re-add the SearchView when navigating back to an ISearchPage, because Xamarin.Forms automatically removes it
                navigationPage.Popped += HandleNavigationPagePopped;
                navigationPage.PoppedToRoot += HandleNavigationPagePopped;
            }
        }

        //Adding the SearchBar in OnSizeChanged ensures the SearchBar is re-added after the device is rotated, because Xamarin.Forms automatically removes it
        protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
        {
            base.OnSizeChanged(w, h, oldw, oldh);

            if (Element is ISearchPage && Element is Page page && page.Parent is NavigationPage navigationPage && navigationPage.CurrentPage is ISearchPage)
            {
                AddSearchToToolbar(page.Title);
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (GetToolbar() is Toolbar toolBar)
                toolBar.Menu?.RemoveItem(Resource.Menu.MainMenu);

            base.Dispose(disposing);
        }

        //Workaround to re-add the SearchView when navigating back to an ISearchPage, because Xamarin.Forms automatically removes it
        void HandleNavigationPagePopped(object sender, NavigationEventArgs e)
        {
            if (sender is NavigationPage navigationPage
                && navigationPage.CurrentPage is ISearchPage)
            {
                AddSearchToToolbar(navigationPage.CurrentPage.Title);
            }
        }

        void AddSearchToToolbar(string pageTitle)
        {
            if (GetToolbar() is Toolbar toolBar
                && toolBar.Menu?.FindItem(Resource.Id.ActionSearch)?.ActionView?.JavaCast<SearchView>().GetType() != typeof(SearchView))
            {
                toolBar.Title = pageTitle;
                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.TextVariationFilter;
                    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);
        }

        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

Brandon Minnick
  • 13,342
  • 15
  • 65
  • 123
0

Used User Control for Navbar. and hide Navigarionbar using

NavigationPage.SetHasNavigationBar (this, false);

Pratik
  • 720
  • 4
  • 20
0

Check following link may be it's help you. and i think it's for your requirement.

http://blog.xhackers.co/xamarin-forms-contentpage-with-searchbar-in-the-navigation-bar/

Placing a SearchBar in the top/navigation bar

How to include view in NavigationBar of Xamarin Forms?

install or update Android support repository, google play service and Google USB driver

enter image description here

Pratik
  • 720
  • 4
  • 20
  • i tried first link yesterday there are some support library issue was there i spend 1 day to get out of it but i cant ..so try to get solution from other options and in second and third link there is no solution for android ....what about android – priya_d Jun 02 '17 at 12:14
0

if you'r using shell app you can use Shell.TitleView instead of Navigation.TitleView as the following :

        <Shell.TitleView>

        <SearchBar x:Name="search"  Margin="10,10,10,10"
                   HorizontalOptions="FillAndExpand"/>



        </Shell.TitleView>
a. 1
  • 13
  • 3