我想将自动填充文本框添加到xamarin.android中的列表视图(自定义对象)。
我有一个listview,它是从字符串数组中填充的。我想使用自定义对象填充我的列表视图。
下面的代码适用于字符串数组。任何帮助实现自定义对象的适配器都会有所帮助。
以下是代码:
Main.axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText
android:id="@+id/search"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
android:hint="Enter search query" />
<Button
android:id="@+id/dosearch"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Filter list" />
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
MainActivity
public class MainActivity : Activity
{
Button _button;
ListView _listview;
EditText _filterText;
FilterableAdapter _adapter;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
_button = FindViewById<Button> (Resource.Id.dosearch);
_listview = FindViewById<ListView> (Resource.Id.list);
_filterText = FindViewById<EditText> (Resource.Id.search);
_adapter = new FilterableAdapter (this, Android.Resource.Layout.SimpleListItem1, GetItems());
_listview.Adapter = _adapter;
_button.Click += delegate {
// filter the adapter here
_adapter.Filter.InvokeFilter(_filterText.Text);
};
_filterText.TextChanged += (object sender, Android.Text.TextChangedEventArgs e) => {
// filter on text changed
var searchTerm = _filterText.Text;
if (String.IsNullOrEmpty(searchTerm)) {
_adapter.ResetSearch();
} else {
_adapter.Filter.InvokeFilter(searchTerm);
}
};
}
string[] GetItems ()
{
string[] names = new string[] { "abc", "xyz", "yyy", "aaa" };
return names;
}
}
public class FilterableAdapter : ArrayAdapter, IFilterable
{
LayoutInflater inflater;
Filter filter;
Activity context;
public string[] AllItems;
public string[] MatchItems;
public FilterableAdapter (Activity context, int txtViewResourceId, string[] items) : base(context, txtViewResourceId, items)
{
inflater = context.LayoutInflater;
filter = new SuggestionsFilter(this);
AllItems = items;
MatchItems = items;
}
public override int Count {
get {
return MatchItems.Length;
}
}
public override Java.Lang.Object GetItem (int position)
{
return MatchItems[position];
}
public override View GetView (int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
view = inflater.Inflate(Android.Resource.Layout.SimpleDropDownItem1Line, null);
view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = MatchItems[position];
return view;
}
public override Filter Filter {
get {
return filter;
}
}
public void ResetSearch() {
MatchItems = AllItems;
NotifyDataSetChanged ();
}
class SuggestionsFilter : Filter
{
readonly FilterableAdapter _adapter;
public SuggestionsFilter (FilterableAdapter adapter) : base() {
_adapter = adapter;
}
protected override Filter.FilterResults PerformFiltering (Java.Lang.ICharSequence constraint)
{
FilterResults results = new FilterResults();
if (!String.IsNullOrEmpty (constraint.ToString ())) {
var searchFor = constraint.ToString ();
Console.WriteLine ("searchFor:" + searchFor);
var matchList = new List<string> ();
var matches =
from i in _adapter.AllItems
where i.IndexOf (searchFor, StringComparison.InvariantCultureIgnoreCase) >= 0
select i;
foreach (var match in matches) {
matchList.Add (match);
}
_adapter.MatchItems = matchList.ToArray ();
Console.WriteLine ("resultCount:" + matchList.Count);
Java.Lang.Object[] matchObjects;
matchObjects = new Java.Lang.Object[matchList.Count];
for (int i = 0; i < matchList.Count; i++) {
matchObjects [i] = new Java.Lang.String (matchList [i]);
}
results.Values = matchObjects;
results.Count = matchList.Count;
} else {
_adapter.ResetSearch ();
}
return results;
}
protected override void PublishResults (Java.Lang.ICharSequence constraint, Filter.FilterResults results)
{
_adapter.NotifyDataSetChanged();
}
}
}
我想让我的getItem方法像这样:
public List<ListObject> GetItems()
{
List<ListObject> model = new List<ListObject>();
model.Add(new ListObject { id = 1, Name = "abc" });
model.Add(new ListObject { id = 1, Name = "bcd" });
model.Add(new ListObject { id = 1, Name = "def" });
model.Add(new ListObject { id = 1, Name = "fgh" });
return model;
}
这样做的主要原因是我希望根据edittext中输入的数据过滤我的列表。然后获取所选的Id并执行剩余的计算。
答案 0 :(得分:0)
具有自定义对象的可过滤适配器
我写了demo关于如何搜索RecyclerView
的内容,在我的演示中,我使用RecyclerView
填充了List<Chemical>
。有关更多详细信息,请阅读我的回答:Searching Through RecyclerView
我的Chemical
课程:
public class Chemical
{
public string Name { get; set; }
public int DrawableId { get; set; }
}
填充RecyclerView
:
var chemicals = new List<Chemical>
{
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},
};
_adapter = new RecyclerViewAdapter(this,chemicals);
由于您使用的是ListView
,因此您可以参考Cheesebaron's SearchView-Sample,我认为这就是您想要的。
不要忘记在项目中添加ObjectExtensions课程。
答案 1 :(得分:0)
我找到了理想的结果。我改变了我的适配器,这对我有用:
public class FilterableAdapter : ArrayAdapter, IFilterable
{
LayoutInflater inflater;
Filter filter;
Activity context;
public List<ListObject> AllItems;
public List<ListObject> MatchItems;
public FilterableAdapter(Activity context, int txtViewResourceId, List<ListObject> items) : base(context, txtViewResourceId, items)
{
inflater = context.LayoutInflater;
filter = new SuggestionsFilter(this);
AllItems = items;
MatchItems = items;
}
public override int Count
{
get
{
return MatchItems.Count;
}
}
public override Java.Lang.Object GetItem(int position)
{
return null;
}
public ListObject GetMatchedItem(int position)
{
return MatchItems[position];
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
view = inflater.Inflate(Resource.Layout.custom_listView, null);
view.FindViewById<TextView>(Resource.Id.list_content).Text = MatchItems[position].PICPropertyName;
return view;
}
public override Filter Filter
{
get
{
return filter;
}
}
public void ResetSearch()
{
MatchItems = AllItems;
NotifyDataSetChanged();
}
class SuggestionsFilter : Filter
{
readonly FilterableAdapter _adapter;
public SuggestionsFilter(FilterableAdapter adapter) : base()
{
_adapter = adapter;
}
protected override Filter.FilterResults PerformFiltering(Java.Lang.ICharSequence constraint)
{
FilterResults results = new FilterResults();
if (!String.IsNullOrEmpty(constraint.ToString()))
{
var searchFor = constraint.ToString();
Console.WriteLine("searchFor:" + searchFor);
var matchList = new List<ListObject>();
var matches = _adapter.AllItems.Where(i => i.name.Contains(searchFor));
foreach (var match in matches)
{
matchList.Add(match);
}
_adapter.MatchItems = matchList;
Console.WriteLine("resultCount:" + matchList.Count);
List<ListObject> matchObjects = new List<ListObject>();
for (int i = 0; i < matchList.Count; i++)
{
matchObjects.Add(matchList[i]);
}
results.Count = matchList.Count;
}
else
{
_adapter.ResetSearch();
}
return results;
}
protected override void PublishResults(Java.Lang.ICharSequence constraint, Filter.FilterResults results)
{
_adapter.NotifyDataSetChanged();
}
}
}
public class ListObject {
public int id { get; set; }
public int name { get; set; }
}