简体   繁体   English

Xamarin Forms - 导航栏中带有 SearchBar 的 ContentPage

[英]Xamarin Forms - ContentPage with SearchBar in the Navigation bar

https://www.linkedin.com/pulse/xamarin-forms-contentpage-searchbar-navigation-bar-vipin-mathews/ https://www.linkedin.com/pulse/xamarin-forms-contentpage-searchbar-navigation-bar-vipin-mathews/

I tried to implement the above code but not succeed, Search Icon not coming in page,我试图实现上面的代码但没有成功,搜索图标没有进入页面,

After that I tried this Adding a Search Bar in the toolbar of a navigationpage in Prism , and its appears but once I changes the orientation or I logout or clicked on other page and come back again at this page its gone之后,我尝试在 Prism 的导航页面的工具栏中添加搜索栏,它出现了,但是一旦我更改方向或注销或单击其他页面并再次返回此页面,它就消失了

I downloaded the code from git but not able to run that also.我从 git 下载了代码,但也无法运行。

<?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/action_search"
        android:title="Search"
        android:icon="@android:drawable/ic_menu_search"
        app:showAsAction="always|collapseActionView"
        app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>

But ic_menu_search file not there in drawable folder, Is that an issue?但是 ic_menu_search 文件不在 drawable 文件夹中,这是一个问题吗?

Just use the TitleView something like:只需使用 TitleView 类似的东西:

<NavigationPage.TitleView>
        <StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
            <Label
                HorizontalOptions="FillAndExpand"
                Text="{StaticResource PageTitle}"
                TextColor="White"
                VerticalOptions="Center" />
            <SearchBar
                HorizontalOptions="End"
                Placeholder="Search"
                PlaceholderColor="{StaticResource GrayPlaceHolderColor}"
                TextColor="White"
                VerticalOptions="Center" />
        </StackLayout>
    </NavigationPage.TitleView>

We can create a custom renderer in both the Xamarin.iOS and Xamarin.Android to accomplish it.我们可以在 Xamarin.iOS 和 Xamarin.Android 中创建自定义渲染器来完成它。

Here's a sample application for reference: https://github.com/brminnick/GitTrends这是一个示例应用程序供参考: 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/这是一篇博客文章,展示了如何为 Xamarin.iOS 和 Xamarin.Android 的 Xamarin.Forms 应用程序添加搜索栏: 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.使用Xamarin.Forms 平台特定在 Xamarin.iOS 应用上使用大标题。

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.创建可跨 Xamarin.Forms、Xamarin.Android 和 Xamarin.iOS 项目使用的接口。

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

Xamarin.Forms Page 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 Custom Renderer 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
    {
        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 Xamarin.Android 菜单 XML

  1. In the Xamarin.Android project, in the Resources folder, create a new folder called menu (if one doesn't already exist).在 Xamarin.Android 项目的Resources文件夹中,创建一个名为menu的新文件夹(如果尚不存在)。

    • Note : the folder, menu , has a lowercase 'm'注意:文件夹menu有一个小写的“m”
  2. In the Resources > menu folder, create a new file called MainMenu.xml .Resources > menu文件夹中,创建一个名为MainMenu.xml的新文件。

在此处输入图片说明

  1. Open Resources > menu > MainMenu.xml打开Resources > menu > MainMenu.xml

  2. In MainMenu.xml add the following code: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 Xamarin.Android 自定义渲染器

Uses the Plugin.CurrentActivity NuGet Package .使用Plugin.CurrentActivity NuGet 包

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 && page.Parent is NavigationPage navigationPage && navigationPage.CurrentPage is ISearchPage)
                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.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);

        }

        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这是一个示例应用程序供参考: 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/以及展示如何为 Xamarin.iOS 和 Xamarin.Android 添加搜索栏的博客文章: https ://www.codetraveler.io/2019/08/10/adding-a-search-bar-to-xamarin- 表单导航页/

iOS GIF

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM