Last active
March 15, 2023 19:30
-
-
Save Cheesebaron/9838325 to your computer and use it in GitHub Desktop.
Custom Adapter with Filter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace SearchViewSample | |
{ | |
public class Chemical | |
{ | |
public string Name { get; set; } | |
public int DrawableId { get; set; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using Android.App; | |
using Android.Views; | |
using Android.Widget; | |
using Java.Lang; | |
using Object = Java.Lang.Object; | |
namespace SearchViewSample | |
{ | |
public class ChemicalsAdapter : BaseAdapter<Chemical>, IFilterable | |
{ | |
private List<Chemical> _originalData; | |
private List<Chemical> _items; | |
private readonly Activity _context; | |
public ChemicalsAdapter(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 View GetView(int position, View convertView, ViewGroup parent) | |
{ | |
var view = convertView ?? _context.LayoutInflater.Inflate(Resource.Layout.Chemical, null); | |
var chemical = _items[position]; | |
var nameView = view.FindViewById<TextView>(Resource.Id.chemName); | |
var imageView = view.FindViewById<ImageView>(Resource.Id.chemImage); | |
nameView.Text = chemical.Name; | |
imageView.SetImageResource(chemical.DrawableId); | |
return view; | |
} | |
public override int Count | |
{ | |
get { return _items.Count; } | |
} | |
public override Chemical this[int position] | |
{ | |
get { return _items[position]; } | |
} | |
public Filter Filter { get; private set; } | |
public override void NotifyDataSetChanged() | |
{ | |
// If you are using cool stuff like sections | |
// remember to update the indices here! | |
base.NotifyDataSetChanged(); | |
} | |
private class ChemicalFilter : Filter | |
{ | |
private readonly ChemicalsAdapter _adapter; | |
public ChemicalFilter(ChemicalsAdapter 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<Object>() | |
.Select(r => r.ToNetObject<Chemical>()).ToList(); | |
_adapter.NotifyDataSetChanged(); | |
// Don't do this and see GREF counts rising | |
constraint.Dispose(); | |
results.Dispose(); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using Android.App; | |
using Android.Runtime; | |
using Android.Support.V4.View; | |
using Android.Support.V7.App; | |
using Android.Support.V7.Widget; | |
using Android.Views; | |
using Android.Widget; | |
using Android.OS; | |
namespace SearchViewSample | |
{ | |
[Activity(Label = "SearchView Sample", MainLauncher = true, Icon = "@drawable/icon", | |
Theme = "@style/Theme.AppCompat.Light")] | |
public class SearchViewActivity : ActionBarActivity | |
{ | |
private SearchView _searchView; | |
private ListView _listView; | |
private ChemicalsAdapter _adapter; | |
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}, | |
}; | |
_listView = FindViewById<ListView>(Resource.Id.listView); | |
_adapter = new ChemicalsAdapter(this, chemicals); | |
_listView.Adapter = _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<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; | |
} | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If people don't want to use the "nasty object wrapping", you can avoid it if you let your class extend Java.Lang.Object itself like:
public class Chemical : Java.Lang.Object
You'd then change the relevant parts in your FilterResults and PublishResults methods:
returnObj.Values = results.ToArray();
_adapter._items = new List<Chemical>(values.ToArray<Chemical>());