2015-05-01 2 views
1

Я использую меню ActionBar как:Xamarin Android: ActionBar SearchView ActionView возвращает нуль

<menu xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item 
     android:id="@+id/menu_search" 
     android:actionViewClass="com.abc.AppSearchView" 
     android:icon="@drawable/ic_menu_search" 
     android:showAsAction="always|collapseActionView" /> 
</menu> 

Тогда я надуть его и:

public override bool OnCreateOptionsMenu (IMenu menu) 
{ 
    MenuInflater.Inflate (Resource.Menu.actionMenu, menu); 
    _actionBarMenu = menu; 
    // Get the SearchView and set the searchable configuration 
    var searchManager = (SearchManager)GetSystemService (SearchService); 
    var searchMenuItem = menu.FindItem (Resource.Id.menu_search); 

    var searchView = (AppSearchView)searchMenuItem.ActionView; 
    // Assumes current activity is the searchable activity 
    searchView.SetSearchableInfo (searchManager.GetSearchableInfo (ComponentName)); 
    searchView.SetSearchViewListener (this); 
    return base.OnCreateOptionsMenu (menu); 
} 

У меня есть пользовательский поиск Просмотр реализации:

public class AppSearchView : SearchView 
{ 
    private IAppSearchViewListener mListener; 

    public AppSearchView (Context ctxt) : base (ctxt) 
    { 

    } 

    public override void OnActionViewCollapsed() 
    { 
     if (mListener != null) 
      mListener.OnSearchViewCollapsed (this); 
     base.OnActionViewCollapsed(); 
    } 

    public override void OnActionViewExpanded() 
    { 
     if (mListener != null) 
      mListener.OnSearchViewExpanded (this); 
     base.OnActionViewExpanded(); 
    } 

    public interface IAppSearchViewListener 
    { 
     void OnSearchViewCollapsed (SearchView sView); 

     void OnSearchViewExpanded (SearchView sView); 
    } 

    public void SetSearchViewListener (IAppSearchViewListener listener) 
    { 
     mListener = listener; 
    } 
} 

searchMenuItem.ActionView is null (Следовательно, поиск имеет значение null). Но этот же код работает в другом приложении, которое у меня есть. Оба приложения используют Xamarin.Android.Support.v13. Кроме того, если я использую android.widget.SearchView, он отлично работает и ActionView не имеет значения. Может ли кто-то пролить некоторый свет на то же самое?

ответ

4

Проблема в том, что вы пытаетесь применить Java-тип к типу .NET. Это работает только для некоторых типов.

Вместо этого в вашей реализации OnCreateOptionsMenu вам понадобится метод расширения .JavaCast<T>(), который поможет вам.

Что-то вроде это работает для меня:

public override bool OnCreateOptionsMenu(IMenu menu) 
{ 
    MenuInflater.Inflate(Resource.Menu.main, menu); 

    var item = menu.FindItem(Resource.Id.action_search); 

    var searchView = MenuItemCompat.GetActionView(item); 
    _searchView = searchView.JavaCast<SearchView>(); 

    _searchView.QueryTextChange += (s, e) => _adapter.Filter.InvokeFilter(e.NewText); 

    _searchView.QueryTextSubmit += (s, e) => 
    { 
     // Handle enter/search button on keyboard here 
     Toast.MakeText(this, "Searched for: " + e.Query, ToastLength.Short).Show(); 
     e.Handled = true; 
    }; 

    MenuItemCompat.SetOnActionExpandListener(item, new SearchViewExpandListener(_adapter)); 

    return true; 
} 

Это SearchViewExpandListener:

private class SearchViewExpandListener 
    : Java.Lang.Object, MenuItemCompat.IOnActionExpandListener 
{ 
    private readonly IFilterable _adapter; 

    public SearchViewExpandListener(IFilterable adapter) 
    { 
     _adapter = adapter; 
    } 

    public bool OnMenuItemActionCollapse(IMenuItem item) 
    { 
     _adapter.Filter.InvokeFilter(""); 
     return true; 
    } 

    public bool OnMenuItemActionExpand(IMenuItem item) 
    { 
     return true; 
    } 
} 

EDIT:

ИТАК выше ответ по-прежнему актуальна, который показывает использование с поддержкой v7. В любом случае, новая версия Xamarin.Android explicity указывает, что все виды и типы, которые вы собираетесь ссылаться в AXML/XML-файлах, должны использовать [Register("my.view.Name")]. Если вы этого не сделаете, когда приложение скомпилировано, вместо вашего пространства имен, которое использовалось ранее, используется контрольная сумма для имени вашего пакета. Это означает, что вы никогда не сможете найти представление.

Так что в вашем пользовательском классе AppSearchView вам нужно добавить RegisterAttributeFlags как:

[Register("com.abc.AppSearchView)] 
public class AppSearchView : SearchView 
{ 
} 

Теперь вы должны быть в состоянии найти ActionView.

Дополнительная информация о нарушениях изменения Xamarin.Android 5 может быть прочитана on the forums.

+0

Фактически свойство ActionView равно NULL для пункта меню поиска. Поэтому использование JavaCast здесь не полезно. Кроме того, я не использую MenuItemCompat, так как поддерживаю устройства выше Android 4.0. Вы думаете, что это изменило бы ситуацию? –

+0

Читать редактирование :) – Cheesebaron

Смежные вопросы