如何實現SearchView到你的ActionBar搜索菜單圖標的Xamarin android Recyclerview listitem?SearchView到你的ActionBar在Xamarin android中的Recyclerview?
回答
我寫了一個關於如何實現此功能的簡單演示,效果如this。你可以在這個GitHub Repository看到它。
- 設置了搜索查看
在文件夾res/menu
創建一個名爲main.xml
新文件。在其中添加一個項目並將actionViewClass
設置爲android.support.v7.widget.SearchView
。由於您使用的是支持庫,因此必須使用支持庫的名稱空間來設置actionViewClass
屬性。你main.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>
在你Activity
你有誇大像往常這個菜單XML,那麼你可以看看其中包含SearchView
的MenuItem
和QueryTextChange
添加一個委託,我們正在準備用來監聽更改到文本輸入到SearchView
:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
SupportActionBar.SetDisplayShowHomeEnabled(true);
var chemicals = new List<Chemical>
{
new Chemical {Name = "Niacin", DrawableId = Resource.Drawable.Icon},
new Chemical {Name = "Biotin", DrawableId = Resource.Drawable.Icon},
new Chemical {Name = "Chromichlorid", DrawableId = Resource.Drawable.Icon},
new Chemical {Name = "Natriumselenit", DrawableId = Resource.Drawable.Icon},
new Chemical {Name = "Manganosulfate", DrawableId = Resource.Drawable.Icon},
new Chemical {Name = "Natriummolybdate", DrawableId = Resource.Drawable.Icon},
new Chemical {Name = "Ergocalciferol", DrawableId = Resource.Drawable.Icon},
new Chemical {Name = "Cyanocobalamin", DrawableId = Resource.Drawable.Icon},
};
_recyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
_adapter = new RecyclerViewAdapter(this,chemicals);
_LayoutManager = new LinearLayoutManager(this);
_recyclerView.SetLayoutManager(_LayoutManager);
_recyclerView.SetAdapter(_adapter);//
}
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<Android.Support.V7.Widget.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;
}
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;
}
}
- 要使用一個Java類型包.NET類型
- 濾波定製適配器
您必須實現自己的Filter
,因爲自定義適配器的本質是您呈現自定義內容。因此默認的Filter
實現無法知道如何過濾。
正如Cheesebaron所說,FilterResult
用於臨時存儲過濾值,預計存儲的對象是Java類型。因此,無論您的模型如何填寫您的Adapte
r必須實施Java.Lang.Object
或者您將不得不包裝您的值。我將向您展示後者,因爲它將適用於更多的使用案例,因爲您可能無法也可能不希望在您的合同中實施Java.Lang.Object
,或者您正在使用什麼來存儲數據,尤其是當您正在通信和共享代碼時平臺之間。
爲了結束.NET
類型的我使用修改後的代碼從該monodroid mailing list thread一個Java類型,它看起來像這樣:
public class JavaHolder : Java.Lang.Object
{
public readonly object Instance;
public JavaHolder(object instance)
{
Instance = instance;
}
}
public static class ObjectExtensions
{
public static TObject ToNetObject<TObject>(this Java.Lang.Object value)
{
if (value == null)
return default(TObject);
if (!(value is JavaHolder))
throw new InvalidOperationException("Unable to convert to .NET object. Only Java.Lang.Object created with .ToJavaObject() can be converted.");
TObject returnVal;
try { returnVal = (TObject)((JavaHolder)value).Instance; }
finally { value.Dispose(); }
return returnVal;
}
public static Java.Lang.Object ToJavaObject<TObject>(this TObject value)
{
if (Equals(value, default(TObject)) && !typeof(TObject).IsValueType)
return null;
var holder = new JavaHolder(value);
return holder;
}
}
的主要區別是,在Java保持器對象被銷燬的立即當它是轉換爲.NET
對象。此外,原始來源中的比較,值是否爲空是不安全的,因爲它不考慮價值類型。對象處置對於保持GREF
引用最小化非常有用。我真的不希望應用程序在內存上運行得很高。
的Adapter
看起來像這樣:
public class RecyclerViewAdapter : RecyclerView.Adapter, IFilterable
{
private List<Chemical> _originalData;
private List<Chemical> _items;
private readonly Activity _context;
public Filter Filter { get; private set; }
public RecyclerViewAdapter(Activity activity, IEnumerable<Chemical> chemicals)
{
_items = chemicals.OrderBy(s => s.Name).ToList();
_context = activity;
Filter = new ChemicalFilter(this);
}
public override long GetItemId(int position)
{
return position;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.Chemical, parent, false);
ChemicalHolder vh = new ChemicalHolder(itemView);
return vh;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
ChemicalHolder vh = holder as ChemicalHolder;
var chemical = _items[position];
vh.Image.SetImageResource(chemical.DrawableId);
vh.Caption.Text = chemical.Name;
}
public override int ItemCount
{
get { return _items.Count; }
}
public class ChemicalHolder : RecyclerView.ViewHolder
{
public ImageView Image { get; private set; }
public TextView Caption { get; private set; }
public ChemicalHolder(View itemView) : base(itemView)
{
Image = itemView.FindViewById<ImageView>(Resource.Id.chemImage);
Caption = itemView.FindViewById<TextView>(Resource.Id.chemName);
}
}
private class ChemicalFilter : Filter
{
private readonly RecyclerViewAdapter _adapter;
public ChemicalFilter(RecyclerViewAdapter adapter)
{
_adapter = adapter;
}
protected override FilterResults PerformFiltering(ICharSequence constraint)
{
var returnObj = new FilterResults();
var results = new List<Chemical>();
if (_adapter._originalData == null)
_adapter._originalData = _adapter._items;
if (constraint == null) return returnObj;
if (_adapter._originalData != null && _adapter._originalData.Any())
{
// Compare constraint to all names lowercased.
// It they are contained they are added to results.
results.AddRange(
_adapter._originalData.Where(
chemical => chemical.Name.ToLower().Contains(constraint.ToString())));
}
// Nasty piece of .NET to Java wrapping, be careful with this!
returnObj.Values = FromArray(results.Select(r => r.ToJavaObject()).ToArray());
returnObj.Count = results.Count;
constraint.Dispose();
return returnObj;
}
protected override void PublishResults(ICharSequence constraint, FilterResults results)
{
using (var values = results.Values)
_adapter._items = values.ToArray<Java.Lang.Object>()
.Select(r => r.ToNetObject<Chemical>()).ToList();
_adapter.NotifyDataSetChanged();
// Don't do this and see GREF counts rising
constraint.Dispose();
results.Dispose();
}
}
}
- 1. Android Actionbar SearchView
- 2. 在ActionBar中顯示SearchView Android
- 3. android actionbar searchview icon change
- 4. SearchView in Actionbar Appcompat
- 5. Honeycomb Actionbar SearchView
- 6. SearchView WITH ACTIONBAR
- 7. 在ActionBar中使用SearchView
- 8. 在ActionBar中展開時的SearchView位置
- 9. SearchView與RecyclerView
- 10. Xamarin searchview OnActionExpandListener
- 11. 將AutoCompleteTextView轉換爲ActionBar中的SearchView
- 12. 在ActionBar上顯示SearchView的軟鍵盤
- 13. 在Actionbar中使用「SearchView」和ActionbarSherlock
- 14. Android如何在Actionbar中設置SearchView風格?
- 15. 我需要在一個RecyclerView中應用SearchView在android
- 16. 更改ActionBar和SearchView的背景圖
- 17. 無盡的滾動與RecyclerView Xamarin Android
- 18. 如何在使用圖像的ListView的Actionbar中創建SearchView?
- 19. RecyclerView單擊項目和SearchView
- 20. 添加Collapsable SearchView Actionbar without action bar
- 21. SearchView在ActionBar vom中的圖標AppCompat始終有一個影子
- 22. 在Xamarin android中使用RecyclerView的Contextual Action Bar?
- 23. 在android中嵌套的ActionBar?
- 24. 在ActionBar上創建「歷史記錄」到SearchView
- 25. RecyclerView中的AsyncTask
- 26. SearchView佔據整個actionBar空間
- 27. ActionBar SearchView無法正常工作
- 28. 防止Android ActionBar選項卡在Xamarin中切換
- 29. 在RecyclerView的Android
- 30. Android Actionbar SearchView更改圖標並刪除多餘間距
https://developer.android.com/guide/topics /search/search-dialog.html Android文檔有一個有用的指導,這將很容易轉換成Xamarin.Android –