如何使用Xamarin.Forms将SearchBar添加到页面顶部(如toolbaritems图标) [英] How to add a SearchBar to the top of page like toolbaritems icon with Xamarin.Forms

查看:198
本文介绍了如何使用Xamarin.Forms将SearchBar添加到页面顶部(如toolbaritems图标)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在此页面中使用masterdetail页面,我现在正在使用选项卡式页面,我想在页面顶部显示工具栏图标和搜索栏.我能够放置工具栏图标,但是却在搜索栏上苦苦挣扎.如何将其放置在顶部的行为应与whatsapp应用程序和youtube应用程序中的搜索栏匹配

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

推荐答案

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

We can create a custom renderer on both Xamarin.iOS and Xamarin.Android to accomplish it.

这里有一个示例应用程序供参考: https://github.com/brminnick/GitTrends

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

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

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/

使用

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

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

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

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的新文件夹(如果尚不存在).

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

  • 注意:文件夹menu的小写字母为'm'
  • Note: the folder, menu, has a lowercase 'm'

Resources > menu文件夹中,创建一个名为MainMenu.xml的新文件.

In the Resources > menu folder, create a new file called MainMenu.xml.

  1. 打开Resources > menu > MainMenu.xml

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软件包.

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);
    }
}

示例应用

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

Sample App

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

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

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.Forms将SearchBar添加到页面顶部(如toolbaritems图标)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆