为Xamarin.Forms的导航栏增加搜索功能

 更新时间:2022年01月29日 09:15:43   作者:痕迹g  
这篇文章介绍了为Xamarin.Forms的导航栏增加搜索功能的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

在使用NavigationPage导航的时候, 我们可以给里面添加一些功能按钮, 如下所示:

    <ContentPage.ToolbarItems>
        <ToolbarItem/>
        <ToolbarItem/>
    </ContentPage.ToolbarItems>

但是如果需要给这个控件添加一些其他的控件的时候, 则无法满足我们的需求, 这个时候, 我们就需要使用 页面渲染器(Page Renderer)。

真机效果演示:

实现思路:

  • 1.添加用于搜索通知的接口 : ISearchPage
  • 2.自定义搜索的渲染器 : SearchPageRender
  • 3.添加Menu/Item Xml文件: mainmenu.xml
  • 4.添加 Nuget:Plugin.CurrentActivity
  • 5.给需要添加搜索功能的页面实现 (1)的接口
  • 6.为自定义搜索渲染器添加支持该功能的页面
  • 7.启动项初始化 : CrossCurrentActivity.Current.Init(this, savedInstanceState)

添加搜索通知接口

    public interface ISearchPage
    {
        void OnSearchBarTextChanged(string text);
    }

自定义渲染器

在Android项目中创建 CustomRender文件夹定义 SearchPageRender

SearchPageRender代码

     public class SearchPageRender : PageRenderer
    {
        public SearchPageRender(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 Android.Support.V7.Widget.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 Android.Support.V7.Widget.Toolbar toolBar
            && toolBar.Menu?.FindItem(Resource.Id.action_search)?.ActionView?.
            JavaCast<Android.Support.V7.Widget.SearchView>().GetType()
            != typeof(Android.Support.V7.Widget.SearchView))
            {
                toolBar.Title = pageTitle;
                toolBar.InflateMenu(Resource.Menu.mainmenu);

                if (toolBar.Menu?.FindItem(Resource.Id.action_search)?.ActionView?.
                    JavaCast<Android.Support.V7.Widget.SearchView>() is
                     Android.Support.V7.Widget.SearchView searchView)
                {
                    searchView.QueryTextChange += SearchView_QueryTextChange;
                    searchView.ImeOptions = (int)ImeAction.Search;
                    searchView.InputType = (int)InputTypes.TextVariationFilter;
                    searchView.MaxWidth = int.MaxValue;
                }
            }
        }

        private void SearchView_QueryTextChange(object sender, Android.Support.V7.Widget.SearchView.QueryTextChangeEventArgs e)
        {
            if (Element is ISearchPage searchPage)
                searchPage.OnSearchBarTextChanged(e.NewText);
        }

        private static Android.Support.V7.Widget.Toolbar GetToolbar() => (CrossCurrentActivity.Current?.Activity as MainActivity)?.FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
    }

添加Xml文件引用SearchView

创建mainmenu.xml

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

添加NuGet:Plugin.CurrentActivity

在Android项目中, 添加NuGet包: Plugin.CurrentActivity , 并且在SearchPageRender 中引用它。

页面实现接口 ISearchPage

渲染器添加实现页

如下图所示, 第一个typeof 指向的就是实现搜索内容页的Page

MainActivity初始化

在MainActivity的 OnCreate 中, 添加初始化的代码, 如下:

以上步骤完整之后, 通过导航页打开的页面即可自带搜索功能。

到此这篇关于为Xamarin.Forms的导航栏增加搜索功能的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C#实现SQL批量插入数据到表的方法

    C#实现SQL批量插入数据到表的方法

    这篇文章主要介绍了C#实现SQL批量插入数据到表的方法,涉及C#批量操作SQL的相关技巧,需要的朋友可以参考下
    2016-04-04
  • 一文探索C#中实现双向链表的方法

    一文探索C#中实现双向链表的方法

    这篇文章主要为大家详细介绍了C#中的双向链表的实现,揭秘双向链表内实现诸多方法的那些事,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • C# byte数组与Image相互转换的方法

    C# byte数组与Image相互转换的方法

    这篇文章介绍了C# byte数组与Image相互转换的方法,有需要的朋友可以参考一下
    2013-10-10
  • C# 汉字与拼音互转的实现示例

    C# 汉字与拼音互转的实现示例

    本文主要介绍了C# 汉字与拼音互转的实现示例,文中根据实例编码详细介绍的十分详尽,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 详解C# WinForm如何优雅的处理异常

    详解C# WinForm如何优雅的处理异常

    在运行、调试代码的时候,会遇到一些异常情况,很多时候我们代码写得足够健壮,所以出现的概率比较低,但如果一出现,我们又没处理好,就可能会导致程序的崩溃、退出。本文主要介绍了WinForm处理异常的方法,需要的可以参考下
    2022-09-09
  • C#制作多线程处理强化版网络爬虫

    C#制作多线程处理强化版网络爬虫

    这篇文章主要介绍了C#制作多线程处理强化版网络爬虫的相关代码,有想学习C#多线程编程的小伙伴可以参考下
    2016-09-09
  • C#设计模式之ChainOfResponsibility职责链模式解决真假美猴王问题实例

    C#设计模式之ChainOfResponsibility职责链模式解决真假美猴王问题实例

    这篇文章主要介绍了C#设计模式之ChainOfResponsibility职责链模式解决真假美猴王问题,简单说明了责任链模式的概念,并结合《西游记》中真假美猴王故事背景为实例分析了责任链模式的具体使用技巧,需要的朋友可以参考下
    2017-09-09
  • C#约瑟夫问题解决方法

    C#约瑟夫问题解决方法

    这篇文章主要介绍了C#约瑟夫问题解决方法,较为详细的分析了约瑟夫问题及C#解决技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-04-04
  • WinFrom中label背景透明的实现方法

    WinFrom中label背景透明的实现方法

    这篇文章主要介绍了WinFrom中label背景透明的实现方法,方法简单实用,是C#程序设计中非常实用的技巧,需要的朋友可以参考下
    2014-09-09
  • C#实现将json转换为DataTable的方法

    C#实现将json转换为DataTable的方法

    这篇文章主要介绍了C#实现将json转换为DataTable的方法,涉及C#操作json及DataTable的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03

最新评论