SearchView 显示错误的 ListView 项目
SearchView displaying wrong ListView items
我的应用程序中的 SearchView 显示不正确的 ListView 项目时遇到问题。
如果我键入名称: ListView 按预期显示
如果我键入 Name1: 我会得到条目 1-2
如果我键入 Name 2-11: 我会得到 Name1
的条目
这是一个视觉效果:
据我所知,代码没有问题,但应用程序未按预期运行。有人可以指出正确的方向来解决这个问题吗?
ListView 使用来自以下数据的自定义数组适配器显示:
[{"society_id":1,"name":"Name1","email":"Test@email1","description":"TestDes1"},
{"society_id":2,"name":"Name2","email":"Test@email2","description":"TestDes2"},
{"society_id":3,"name":"Name3","email":"Test@email3","description":"TestDes3"},...]
SocietySearch.java:
public class SocietySearch extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) { //TODO remember notifyDataSetChanged
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_society_search);
List<Society> societies = new ArrayList<>();
ServerRequests serverRequest1 = new ServerRequests(SocietySearch.this);
serverRequest1.GetSocietyDataAsyncTask(societies, new GetSocietyCallback() {
@Override
public void done(final List<Society> societies) {
ListView lv = (ListView) findViewById(R.id.ListView);
List<ListViewItem> items = new ArrayList<>();
for (final Society s : societies) {
items.add(new ListViewItem() {{
ThumbnailResource = R.drawable.test;
Title = s.socName;
Description = s.socDes;
}});
}
final CustomListViewAdapter adapter = new CustomListViewAdapter(SocietySearch.this, items, societies);
lv.setAdapter(adapter);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) findViewById(R.id.search);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setQueryHint("Search..");
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
}
});
}
public class ListViewItem {
public int ThumbnailResource;
public String Title;
public String Description;
}
CustomListViewAdapter.java:
public class CustomListViewAdapter extends ArrayAdapter {
LayoutInflater inflater;
List<SocietySearch.ListViewItem> items;
public CustomListViewAdapter(Activity context, List<SocietySearch.ListViewItem> items, List<Society> societies) {
super(context, R.layout.item_row, societies);
this.items = items;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
//Auto-generated method stub
ListViewItem item = items.get(position);
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.item_row, null);
ImageView test = (ImageView) vi.findViewById(R.id.imgThumbnail);
TextView txtTitle = (TextView) vi.findViewById(R.id.txtTitle);
TextView txtSubTitle = (TextView) vi.findViewById(R.id.txtSubTitle);
test.setImageResource(item.ThumbnailResource);
txtTitle.setText(item.Title);
txtSubTitle.setText(item.Description);
return vi;
}
}
Society.java:
public class Society {
String socName, socEmail, socDes;
int society_id;
public Society(int society_id, String socName, String socEmail, String socDes) {
this.society_id = society_id;
this.socName = socName;
this.socEmail = socEmail;
this.socDes = socDes;
}
public String toString() {
return socName;
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="k.unionapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".HomeScreenActivity"
android:theme="@style/AppTheme.NoActionBar"></activity>
<activity android:name=".SocietySearch"></activity>
</application>
</manifest>
我相信你的问题可能是因为你在内存中保留了原始列表,并将你的观点与它绑定
ListViewItem item = items.get(position);
相反,您可能想尝试从适配器本身获取项目,因为底层列表正在被 Filter
ListViewItem item = this.getItem(position);
您需要在 SocietySearch.ListViewItem
class 中提供 toString
方法的实现,这将 return 项目名称。
public class ListViewItem {
public int ThumbnailResource;
public String Title;
public String Description;
@Override
public String toString(){
return Title;
}
}
ArrayAdapter
中过滤器的默认实现使用此方法将任意项类型转换为 String
,然后再将其与搜索查询进行比较。此外,默认实现 - ArrayFilter
- 使用查询字符串作为前缀,仅供参考。
此外,如其他答案中所述 - 不要在构造函数和 getView
方法中保留原始列表。使用数组适配器本身的 getItem
方法。
您可能还想更改 class 声明以包含自定义类型的项目而不是通用的 Object
:
public class CustomListViewAdapter extends ArrayAdapter<SocietySearch.ListViewItem> {
我的应用程序中的 SearchView 显示不正确的 ListView 项目时遇到问题。
如果我键入名称: ListView 按预期显示
如果我键入 Name1: 我会得到条目 1-2
如果我键入 Name 2-11: 我会得到 Name1
的条目这是一个视觉效果:
据我所知,代码没有问题,但应用程序未按预期运行。有人可以指出正确的方向来解决这个问题吗?
ListView 使用来自以下数据的自定义数组适配器显示:
[{"society_id":1,"name":"Name1","email":"Test@email1","description":"TestDes1"},
{"society_id":2,"name":"Name2","email":"Test@email2","description":"TestDes2"},
{"society_id":3,"name":"Name3","email":"Test@email3","description":"TestDes3"},...]
SocietySearch.java:
public class SocietySearch extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) { //TODO remember notifyDataSetChanged
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_society_search);
List<Society> societies = new ArrayList<>();
ServerRequests serverRequest1 = new ServerRequests(SocietySearch.this);
serverRequest1.GetSocietyDataAsyncTask(societies, new GetSocietyCallback() {
@Override
public void done(final List<Society> societies) {
ListView lv = (ListView) findViewById(R.id.ListView);
List<ListViewItem> items = new ArrayList<>();
for (final Society s : societies) {
items.add(new ListViewItem() {{
ThumbnailResource = R.drawable.test;
Title = s.socName;
Description = s.socDes;
}});
}
final CustomListViewAdapter adapter = new CustomListViewAdapter(SocietySearch.this, items, societies);
lv.setAdapter(adapter);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) findViewById(R.id.search);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setQueryHint("Search..");
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
}
});
}
public class ListViewItem {
public int ThumbnailResource;
public String Title;
public String Description;
}
CustomListViewAdapter.java:
public class CustomListViewAdapter extends ArrayAdapter {
LayoutInflater inflater;
List<SocietySearch.ListViewItem> items;
public CustomListViewAdapter(Activity context, List<SocietySearch.ListViewItem> items, List<Society> societies) {
super(context, R.layout.item_row, societies);
this.items = items;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
//Auto-generated method stub
ListViewItem item = items.get(position);
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.item_row, null);
ImageView test = (ImageView) vi.findViewById(R.id.imgThumbnail);
TextView txtTitle = (TextView) vi.findViewById(R.id.txtTitle);
TextView txtSubTitle = (TextView) vi.findViewById(R.id.txtSubTitle);
test.setImageResource(item.ThumbnailResource);
txtTitle.setText(item.Title);
txtSubTitle.setText(item.Description);
return vi;
}
}
Society.java:
public class Society {
String socName, socEmail, socDes;
int society_id;
public Society(int society_id, String socName, String socEmail, String socDes) {
this.society_id = society_id;
this.socName = socName;
this.socEmail = socEmail;
this.socDes = socDes;
}
public String toString() {
return socName;
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="k.unionapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".HomeScreenActivity"
android:theme="@style/AppTheme.NoActionBar"></activity>
<activity android:name=".SocietySearch"></activity>
</application>
</manifest>
我相信你的问题可能是因为你在内存中保留了原始列表,并将你的观点与它绑定
ListViewItem item = items.get(position);
相反,您可能想尝试从适配器本身获取项目,因为底层列表正在被 Filter
ListViewItem item = this.getItem(position);
您需要在 SocietySearch.ListViewItem
class 中提供 toString
方法的实现,这将 return 项目名称。
public class ListViewItem {
public int ThumbnailResource;
public String Title;
public String Description;
@Override
public String toString(){
return Title;
}
}
ArrayAdapter
中过滤器的默认实现使用此方法将任意项类型转换为 String
,然后再将其与搜索查询进行比较。此外,默认实现 - ArrayFilter
- 使用查询字符串作为前缀,仅供参考。
此外,如其他答案中所述 - 不要在构造函数和 getView
方法中保留原始列表。使用数组适配器本身的 getItem
方法。
您可能还想更改 class 声明以包含自定义类型的项目而不是通用的 Object
:
public class CustomListViewAdapter extends ArrayAdapter<SocietySearch.ListViewItem> {