我已经根据SearchView输入正确实现了一个ListView(附带标题)过滤。现在我打算让SearchView过滤几个ListViews,我想知道该怎么做。我被困住了,没有任何想法。过滤的主要原则是这样的: 我们有几个类别(即住宿,名胜古迹),它们作为标题(基本上是类别的图片)显示,每个类别都附有ListView。当用户输入搜索查询时,应用程序需要立即过滤所有ListView。窗口的结构如下:
- >当前类别的标头
ListView#1
当用户输入输入时,将显示所有可用类别,并为其应用过滤器:
- >当前类别的标头
过滤后的ListView#1
- >标题#2
过滤后的ListView#2
...
- >标题#8
过滤后的ListView#8
我寻求最清晰/最天才的方式来执行此操作。值得一提的是,我们知道确切的类别数量。
我正在发布我的代码片段(ONE ListView(附带标题)根据SearchView输入进行过滤)。此外,如果搜索没有返回任何结果,我打印该消息,以便用户可以联系我们,如果他愿意的话。 list_header.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/top"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_weight="1"
android:gravity="center">
<View
android:id="@+id/line_left1"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="0.45"
android:background="#FFFFFF" />
<ImageView
android:id="@+id/small_icon"
android:layout_width="60dp"
android:layout_height="80dp"
android:layout_weight="0.1"
android:src="@drawable/pavalgyk" />
<View
android:id="@+id/line_left2"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="0.45"
android:background="#FFFFFF" />
</LinearLayout>
</LinearLayout>
alllists.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="5dp"
android:background="@drawable/background"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="5dp">
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
android:background="@drawable/card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/search_window_text"
android:textSize="16dp"
android:textStyle="normal"
android:autoLink="email"
android:fontFamily="sans-serif-light" />
</RelativeLayout>
</LinearLayout>
AllLists.java
public class AllLists extends android.support.v4.app.Fragment {
private TypedArray navMenuIcons;
private Context context = null;
private int position = 0;
private String location;
private List<Item> items = new ArrayList<Item>();
private List<Item> tmp_items = new ArrayList<Item>();
private ListView listView;
private CustomListAdapter adapter;
private SearchView mSearchView;
private String tmp_s = "";
private static Locale myLocale;
private EasyTracker easyTracker = null;
private RelativeLayout relativeLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.alllists, container, false);
View header = inflater.inflate(R.layout.list_header, null);
ImageView image = (ImageView) header.findViewById(R.id.small_icon);
relativeLayout = (RelativeLayout) rootView.findViewById(R.id.relativeLayout);
relativeLayout.setVisibility(View.GONE);
setLanguage();
navMenuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons);
Bundle bundle = getArguments();
position = bundle.getInt("position");
location = bundle.getString("location");
image.setImageDrawable(navMenuIcons.getDrawable(position));
context = getActivity().getApplicationContext();
easyTracker = EasyTracker.getInstance(context);
DatabaseHandler db = new DatabaseHandler(context);
items = db.getAllItems(location);
tmp_items = db.getAllItems(location);
listView = (ListView) rootView.findViewById(R.id.list);
adapter = new CustomListAdapter(context, items);
listView.addHeaderView(header, "", false);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int list_position, long id) {
easyTracker.send(MapBuilder.createEvent("List",
location, adapter.getItems().get(list_position - 1).getName(), null).build());
if (location.equals("accommodation") || location.equals("eat") || location.equals("events")
|| location.equals("entertainment") || location.equals("places") || location.equals("cinema")) {
Intent i = new Intent(context, ItemScreen.class);
i.putExtra("position", list_position - 1);
i.putExtra("location", location);
i.putExtra("name", adapter.getItems().get(list_position - 1).getRealName());
startActivity(i);
} else if (location.equals("taxi")) {
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + adapter.getItems().get(list_position - 1).getType()));
PackageManager manager = context.getPackageManager();
List<ResolveInfo> infos = manager.queryIntentActivities(intent, 0);
if (infos.size() > 0)
startActivity(intent);
else
Toast.makeText(context, R.string.cant_handle, Toast.LENGTH_SHORT).show();
}
}
});
setHasOptionsMenu(true);
return rootView;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
@Override
public boolean onQueryTextChange(String s) {
easyTracker.send(MapBuilder.createEvent("Search",
"search", s, null).build());
if (TextUtils.isEmpty(s)) {
adapter = new CustomListAdapter(context, tmp_items);
listView.setAdapter(adapter);
}
if (tmp_s.length() > s.length()) {
adapter.getFilter(tmp_items, true).filter(s, new Filter.FilterListener() {
public void onFilterComplete(int count) {
if (count == 0)
relativeLayout.setVisibility(View.VISIBLE);
else
relativeLayout.setVisibility(View.GONE);
}
});
} else {
adapter.getFilter(tmp_items, false).filter(s, new Filter.FilterListener() {
@Override
public void onFilterComplete(int count) {
if (count == 0)
relativeLayout.setVisibility(View.VISIBLE);
else
relativeLayout.setVisibility(View.GONE);
}
});
}
tmp_s = s;
return false;
}
});
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
mSearchView.setQuery("", false);
}
}
CustomListAdapted.java
public class CustomListAdapter extends BaseAdapter {
private Context context;
private List<Item> items;
private LayoutInflater inflater;
private ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public CustomListAdapter(Context context, List<Item> items) {
this.context = context;
this.items = items;
}
@Override
public int getCount() {
return items.size();
}
@Override
public Object getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_item, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
NetworkImageView image = (NetworkImageView) convertView.findViewById(R.id.image);
TextView name = (TextView) convertView.findViewById(R.id.name);
TextView type = (TextView) convertView.findViewById(R.id.type);
Item i = items.get(position);
image.setImageUrl(i.getIcon(), imageLoader);
if(items.get(0).getName().contains("taksi"))
image.setDefaultImageResId(R.drawable.telefonas);
else
image.setDefaultImageResId(R.drawable.be_fono);
name.setText(i.getRealName());
type.setText(i.getType());
return convertView;
}
public List<Item> getItems(){
return items;
}
public Filter getFilter(final List<Item> all_items, final boolean deleted) {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults results = new FilterResults();
if (charSequence == null || charSequence.length() == 0) {
results.values = items;
results.count = items.size();
} else {
List<Item> filtered_items = new ArrayList<Item>();
if(deleted)
items = all_items;
for (int i = 0; i < items.size(); i++) {
String modifiedName = items.get(i).getRealName().toLowerCase();
String modifiedQuery = charSequence.toString().toLowerCase();
modifiedName = encode_lithuanian(modifiedName);
modifiedQuery = encode_lithuanian(modifiedQuery);
if (modifiedName.contains(modifiedQuery))
filtered_items.add(items.get(i));
}
results.values = filtered_items;
results.count = filtered_items.size();
}
return results;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
items = (List<Item>) filterResults.values;
notifyDataSetChanged();
}
public int show_size(){
return items.size();
}
};
}
}
答案 0 :(得分:0)
为不同的列表视图创建适配器。 然后在edittext aftertextchange监听器中为所有适配器应用文本过滤器。看看:
http://www.androidbegin.com/tutorial/android-search-listview-using-filter/
adapter1 = new ListViewAdapter(this, arraylist1);
list1.setAdapter(adapter1);
adapter2 = new ListViewAdapter(this, arraylist2);
list2.setAdapter(adapter2);
editsearch.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable arg0) {
//TODO Auto-generated method stub
String text = editsearch.getText().toString().toLowerCase(Locale.getDefault());
adapter1.filter(text);
adapter2.filter(text);
....
}
答案 1 :(得分:0)
@ Riasat的回答激发了我的灵感,我认为可以在没有任何代码重复的情况下做到这一点:当然对于每个列表视图,你有一个适配器将或多或少相同。但是创建一个通知器可能会很棒,该通知器会对所有适配器进行刷新。类似的东西:
作为您唯一要求的接口:
/**
* Created by laurentmeyer on 03/03/15.
*/
public interface RefreshInterface {
void refresh();
void searchForText(String searchedText);
void searchWithSomethingElse(Object SomethingElse);
}
然后修改适配器:
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
/**
* Created by laurentmeyer on 03/03/15.
*/
public class CustomListAdapter extends BaseAdapter implements RefreshInterface{
private Context context;
private List<Item> items;
private LayoutInflater inflater;
private ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public CustomListAdapter(Context context, List<Item> items) {
this.context = context;
this.items = items;
}
@Override
public int getCount() {
return items.size();
}
@Override
public Object getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_item, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
NetworkImageView image = (NetworkImageView) convertView.findViewById(R.id.image);
TextView name = (TextView) convertView.findViewById(R.id.name);
TextView type = (TextView) convertView.findViewById(R.id.type);
Item i = items.get(position);
image.setImageUrl(i.getIcon(), imageLoader);
if(items.get(0).getName().contains("taksi"))
image.setDefaultImageResId(R.drawable.telefonas);
else
image.setDefaultImageResId(R.drawable.be_fono);
name.setText(i.getRealName());
type.setText(i.getType());
return convertView;
}
public List<Item> getItems(){
return items;
}
public Filter getFilter(final List<Item> all_items, final boolean deleted) {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults results = new FilterResults();
if (charSequence == null || charSequence.length() == 0) {
results.values = items;
results.count = items.size();
} else {
List<Item> filtered_items = new ArrayList<Item>();
if(deleted)
items = all_items;
for (int i = 0; i < items.size(); i++) {
String modifiedName = items.get(i).getRealName().toLowerCase();
String modifiedQuery = charSequence.toString().toLowerCase();
modifiedName = encode_lithuanian(modifiedName);
modifiedQuery = encode_lithuanian(modifiedQuery);
if (modifiedName.contains(modifiedQuery))
filtered_items.add(items.get(i));
}
results.values = filtered_items;
results.count = filtered_items.size();
}
return results;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
items = (List<Item>) filterResults.values;
notifyDataSetChanged();
}
public int show_size(){
return items.size();
}
};
}
// What you'll do when you'll want to refresh (why not?)
@Override
public void refresh() {
}
// What you'll do when you'll want to search from SearchView
@Override
public void searchForText(String searchedText) {
}
// What you'll do when you'll want to have a look with another cool Object like a LatLong or some other stuff (optional, of course)
@Override
public void searchWithSomethingElse(Object SomethingElse) {
}
}
然后你的片段也会改变一点,但不会像其他解决方案那样多:
import java.util.ArrayList;
/**
* Created by laurentmeyer on 03/03/15.
*/
public class AllLists extends android.support.v4.app.Fragment {
private TypedArray navMenuIcons;
private Context context = null;
private int position = 0;
private String location;
private List<Item> items = new ArrayList<Item>();
private List<Item> tmp_items = new ArrayList<Item>();
private ListView listView;
private CustomListAdapter adapter;
private SearchView mSearchView;
private String tmp_s = "";
private static Locale myLocale;
private EasyTracker easyTracker = null;
private RelativeLayout relativeLayout;
/*
Here is a modification
*/
// Create a ArrayList containing all the adapters (which are directly connected to the listViews)
// which will need to be refreshed by the search view. I made it static because maybe you can use
// it in other instances and it could be easier.
public static ArrayList<RefreshInterface> toBeRefreshed;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.alllists, container, false);
View header = inflater.inflate(R.layout.list_header, null);
ImageView image = (ImageView) header.findViewById(R.id.small_icon);
relativeLayout = (RelativeLayout) rootView.findViewById(R.id.relativeLayout);
relativeLayout.setVisibility(View.GONE);
setLanguage();
navMenuIcons = getResources().obtainTypedArray(R.array.nav_drawer_icons);
Bundle bundle = getArguments();
position = bundle.getInt("position");
location = bundle.getString("location");
image.setImageDrawable(navMenuIcons.getDrawable(position));
context = getActivity().getApplicationContext();
easyTracker = EasyTracker.getInstance(context);
DatabaseHandler db = new DatabaseHandler(context);
items = db.getAllItems(location);
tmp_items = db.getAllItems(location);
listView = (ListView) rootView.findViewById(R.id.list);
adapter = new CustomListAdapter(context, items);
/*
Here is a modification
*/
toBeRefreshed.add(adapter);
listView.addHeaderView(header, "", false);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int list_position, long id) {
easyTracker.send(MapBuilder.createEvent("List",
location, adapter.getItems().get(list_position - 1).getName(), null).build());
if (location.equals("accommodation") || location.equals("eat") || location.equals("events")
|| location.equals("entertainment") || location.equals("places") || location.equals("cinema")) {
Intent i = new Intent(context, ItemScreen.class);
i.putExtra("position", list_position - 1);
i.putExtra("location", location);
i.putExtra("name", adapter.getItems().get(list_position - 1).getRealName());
startActivity(i);
} else if (location.equals("taxi")) {
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:" + adapter.getItems().get(list_position - 1).getType()));
PackageManager manager = context.getPackageManager();
List<ResolveInfo> infos = manager.queryIntentActivities(intent, 0);
if (infos.size() > 0)
startActivity(intent);
else
Toast.makeText(context, R.string.cant_handle, Toast.LENGTH_SHORT).show();
}
}
});
setHasOptionsMenu(true);
return rootView;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
MenuItem searchItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
@Override
public boolean onQueryTextChange(String s) {
easyTracker.send(MapBuilder.createEvent("Search",
"search", s, null).build());
if (TextUtils.isEmpty(s)) {
adapter = new CustomListAdapter(context, tmp_items);
listView.setAdapter(adapter);
}
if (tmp_s.length() > s.length()) {
/*
Here call the logic you implemented in your adapter functions like:
for (RefreshInterface r : toBeRefreshed){
r.filter(String)
}
*/
} else {
/*
Same as above
*/
}
tmp_s = s;
return false;
}
});
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
mSearchView.setQuery("", false);
}
}