如何使用Xamarin.Forms将SearchBar添加到页面顶部,如toolbaritems图标

时间:2017-06-01 08:38:06

标签: xamarin.forms

我正在使用此页面中的masterdetail页面我正在使用标签页现在我想在页面顶部显示工具栏图标和搜索栏。我可以放置工具栏图标但是在搜索栏中挣扎。如何将其放置在顶部的行为应该与whatsapp app和youtube app中的搜索栏相匹配

5 个答案:

答案 0 :(得分:1)

WhatsApp搜索栏就是这样一个SearchBar控件,您可以按如下方式添加到XAML布局:

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

确保您具有过滤器的支持属性。您可以使用此属性的setter拦截过滤数据的人员并相应地过滤Items属性。

YouTube搜索的行为略有不同。工具栏项以模态方式弹出一个新屏幕,其中搜索的处理类似于UISearchController(在iOS上)。没有Xamarin Forms插入控件(我很清楚)会为您执行此操作,因此您可能需要自己动手。

答案 1 :(得分:0)

Navbar的用户控件。并使用

隐藏Navigarionbar

NavigationPage.SetHasNavigationBar(this,false);

答案 2 :(得分:0)

检查以下链接可能对您有所帮助。我认为这符合你的要求。

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?

安装或更新Android支持存储库,Google Play服务和Google USB驱动程序

enter image description here

答案 3 :(得分:0)

我们可以在Xamarin.iOS和Xamarin.Android上创建自定义渲染器。

以下是示例应用程序供参考: https://github.com/brminnick/GitTrends

这是一篇博客文章,显示如何为Xamarin.iOS和Xamarin.Android的Xamarin.Forms应用添加搜索栏:https://www.codetraveler.io/2019/08/10/adding-a-search-bar-to-xamarin-forms-navigationpage/

App.cs

使用Xamarin.Forms Platform-Specific在Xamarin.iOS应用上使用LargeTitles。

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界面

创建一个可在Xamarin.Forms,Xamarin.Android和Xamarin.iOS项目中使用的界面。

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

Xamarin.Forms页面

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自定义渲染器

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菜单XML

  1. 在Xamarin.Android项目的Resources文件夹中,创建一个名为menu的新文件夹(如果尚不存在)。

    • 注意:文件夹menu的小写字母'm'
  2. Resources > menu文件夹中,创建一个名为MainMenu.xml的新文件。

enter image description here

  1. 打开Resources > menu > MainMenu.xml

  2. MainMenu.xml中添加以下代码:

<?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

使用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)
            {
                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);
    }
}

示例应用

以下是示例应用供参考: https://github.com/brminnick/GitTrends

还有一篇博客文章,显示了如何为Xamarin.iOS和Xamarin.Android添加搜索栏:https://www.codetraveler.io/2019/08/10/adding-a-search-bar-to-xamarin-forms-navigationpage/

iOS Gif

答案 4 :(得分:0)

如果您使用的是Shell应用程序,则可以使用Shell.TitleView代替Navigation.TitleView,如下所示:

        <Shell.TitleView>

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



        </Shell.TitleView>