Tabs SherlockListFragment中的SearchView
我在SherlockListFragment中使用SearchView时遇到一些问题。有一个自定义的ArrayAdapter和一个listview,其中每个项目包含一个图像和两个文本视图。在我为我的ListFragment应用SearchView之前,一切都很好。搜索图标是可展开的,我还可以在搜索栏中输入单词 问题 自定义适配器现在可以过滤listview,但当我从可展开的searchview中删除最后一个字母或关闭searchview时,应用程序崩溃 我已经附上了我的ArrayAdapter类,以及下面我的SherlockListFragment 带有筛选器类的自定义阵列适配器Tabs SherlockListFragment中的SearchView,tabs,actionbarsherlock,android-viewpager,android-listfragment,searchview,Tabs,Actionbarsherlock,Android Viewpager,Android Listfragment,Searchview,我在SherlockListFragment中使用SearchView时遇到一些问题。有一个自定义的ArrayAdapter和一个listview,其中每个项目包含一个图像和两个文本视图。在我为我的ListFragment应用SearchView之前,一切都很好。搜索图标是可展开的,我还可以在搜索栏中输入单词 问题 自定义适配器现在可以过滤listview,但当我从可展开的searchview中删除最后一个字母或关闭searchview时,应用程序崩溃 我已经附上了我的ArrayAdapter类
public static class ShopListAdapter extends ArrayAdapter<ShopEntry>
{
private final LayoutInflater mInflater;
private List<ShopEntry> filteredData;
private List<ShopEntry> originalData;
public ShopListAdapter(Context context, List<ShopEntry> filteredData)
{
super(context, android.R.layout.simple_list_item_2, filteredData);
mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.filteredData = filteredData;
}
public void setData(List<ShopEntry> data)
{
clear();
if(data != null)
{
for(ShopEntry ShopEntry : data)
{
add(ShopEntry);
}
}
filteredData = data;
originalData = data;
}
@Override
public int getCount()
{
return filteredData.size();
}
@Override
public ShopEntry getItem(int pos)
{
return filteredData.get(pos);
}
/**
* Populate new items in the list.
*/
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View view;
if(convertView == null)
{
view = mInflater.inflate(R.layout.specific_shop_list_item,
parent, false);
}
else
{
view = convertView;
}
ShopEntry item = filteredData.get(position);
String url = item.getImg();
((SmartImageView) view.findViewById(R.id.shopImg)).setImageUrl(url);
((TextView) view.findViewById(R.id.shopType)).setText(item
.getShopName());
view.setBackgroundColor(0xff1e8e8);
return view;
}
private class MyFilter extends Filter
{
@SuppressWarnings("unchecked" )
@Override
protected void publishResults(CharSequence constraint,
FilterResults results)
{
if(results != null && results.count > 0)
{
filteredData = (ArrayList<ShopEntry>) results.values;
notifyDataSetChanged();
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
constraint = constraint.toString();
filteredData = originalData;
if(constraint.length() == 0 || constraint.equals(""))
{
FilterResults original = new FilterResults();
original.count = filteredData.size();
original.values = filteredData;
return original;
}
else
{
List<ShopEntry> filtered = new ArrayList<ShopEntry>();
for(ShopEntry l : filteredData)
{
if(l.getShopName().contains(constraint))
{ // YOU NEED TO CHANGE THIS
filtered.add(l);
Log.d("filter", "filter " + constraint + " "
+ l.getShopName().toString());
}
}
FilterResults newFilterResults = new FilterResults();
newFilterResults.count = filtered.size();
newFilterResults.values = filtered;
return newFilterResults;
}
}
}
MyFilter mFilter;
@Override
public Filter getFilter()
{
if(mFilter == null)
{
mFilter = new MyFilter();
}
return mFilter;
}
}
public class ShopListFragment extends SherlockListFragment implements
LoaderManager.LoaderCallbacks<List<ShopEntry>>, OnQueryTextListener
{
List<ShopEntry> shopEntry = new ArrayList<ShopEntry>();
// This is the Adapter being used to display the list's data.
ShopListAdapter mAdapter;
SearchView searchView;
// If non-null, this is the current filter the user has provided.
String mCurFilter = "";
OnQueryTextListenerCompat mOnQueryTextListenerCompat;
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
// Give some text to display if there is no data. In a real
// application this would come from a resource.
setEmptyText("No Such Shop");
// We have a menu item to show in action bar.
setHasOptionsMenu(true);
// Create an empty adapter we will use to display the loaded data.
mAdapter = new ShopListAdapter(getActivity(), shopEntry);
setListAdapter(mAdapter);
// Start out with a progress indicator.
setListShown(false);
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
// Place an action bar item for searching.
// super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_with_search, menu);
MenuItem item = menu.findItem(R.id.action_search);
searchView = new SearchView(getSherlockActivity().getSupportActionBar()
.getThemedContext());
searchView.setQueryHint(getString(R.string.search_hint));
searchView.setOnQueryTextListener(this);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if(currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH)
{
item.setOnActionExpandListener(new OnActionExpandListener()
{
@Override
public boolean onMenuItemActionCollapse(MenuItem item)
{
searchView.onActionViewCollapsed();
searchView.setQuery(null, true);
searchView.clearFocus();
return true; // Return true to collapse action view
}
@Override
public boolean onMenuItemActionExpand(MenuItem item)
{
// TODO Auto-generated method stub
return true;
}
});
}
else
{
// do something for phones running an SDK before froyo
searchView.setOnCloseListener(new OnCloseListener()
{
@Override
public boolean onClose()
{
searchView.onActionViewCollapsed();
searchView.setQuery(null, true);
searchView.clearFocus();
return false;
}
});
}
item.setActionView(searchView);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onQueryTextChange(String newText)
{ // called when the action bar search text has changed. Update
// the search filter, and restart the loader to do a new query
// with this filter.
String newFilter = !TextUtils.isEmpty(newText) ? newText : null;
// Don't do anything if the filter hasn't actually changed.
// Prevents restarting the loader when restoring state.
if(mCurFilter == null && newFilter == null)
{
return true;
}
if(mCurFilter != null && mCurFilter.equals(newFilter))
{
return true;
}
mCurFilter = newFilter;
mAdapter.getFilter().filter(mCurFilter.toString());
getLoaderManager().restartLoader(0, null, this);
return true;
}
@Override
public boolean onQueryTextSubmit(String query)
{
// TODO Auto-generated method stub
return true;
}
@Override
public Loader<List<ShopEntry>> onCreateLoader(int id, Bundle args)
{
// This is called when a new Loader needs to be created. This
// sample only has one Loader with no arguments, so it is simple.
return new ShopListLoader(getActivity());
}
@Override
public void onLoadFinished(Loader<List<ShopEntry>> loader,
List<ShopEntry> data)
{
// Set the new data in the adapter.
mAdapter.setData(data);
// The list should now be shown.
if(isResumed())
{
setListShown(true);
}
else
{
setListShownNoAnimation(true);
}
}
@Override
public void onLoaderReset(Loader<List<ShopEntry>> loader)
{
// Clear the data in the adapter.
mAdapter.setData(null);
}
}
有人能帮我吗?thx当Sherlock中的
搜索视图
展开时,它会将文本视图
组件设置为”
,您可以从源代码中看到它:
@Override
public void onActionViewExpanded() {
if (mExpandedInActionView) return;
mExpandedInActionView = true;
mCollapsedImeOptions = mQueryTextView.getImeOptions();
mQueryTextView.setImeOptions(mCollapsedImeOptions | EditorInfo.IME_FLAG_NO_FULLSCREEN);
mQueryTextView.setText("");
setIconified(false);
}
这就是过滤器返回原始数据的原因。相反,与android.widget.SearchView相比,当action视图也折叠时,它不会将查询设置为“”。长话短说,您需要用“”省略筛选(除非需要),并且还要检查在执行筛选时是否使列表视图无效,因为您尚未发布筛选实现
编辑:筛选listview的示例
私有类MyFilter扩展了过滤器{
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results!=null && results.count > 0) {
items = (ArrayList<Data>) results.values;
notifyDataSetChanged();
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
items = mOriginalData;
if (constraint.length() == 0 || constraint.equals("")) {
FilterResults original = new FilterResults();
original.count = items.size();
original.values = items;
return original;
} else {
List<Data> filtered = new ArrayList<Data>();
for (Data l : items) {
if ( SOME CONDITION TO FILTER ){ // YOU NEED TO CHANGE THIS
filtered.add(l);
}
}
FilterResults newFilterResults = new FilterResults();
newFilterResults.count = filtered.size();
newFilterResults.values = filtered;
return newFilterResults;
}
}
在这里查看我的答案谢谢你的回答。请查看编辑后的版本。这一次,它不会返回原始列表,而是显示“No shop”,即使我键入了与列表中文本匹配的内容。更奇怪的是,我发现只有在键入包名时,它才不会显示“No shop”,但列表将保持不变。知道为什么吗?哦,你的意思是我不能在onQueryTextChange中仅使用mAdapter.getFilter?你能提供一些示例或给我一些提示,说明如何根据我上面提供的ShopListAdapter方法在适配器中筛选项吗?提前感谢我刚刚上传了完整的java代码。那么,我应该把priv放在哪里ate类MyFilter扩展了Filter?在我的情况下,我应该用什么替换“items”呢?谢谢如果你想保持类私有,请将它与适配器放在同一个类文件中。因此,私有类MyFilter和筛选器类都必须放在我的适配器类ISIT?和“items”中引用列表,对吗?以及如何调用onQueryTextChange()中的筛选器类?谢谢。
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results!=null && results.count > 0) {
items = (ArrayList<Data>) results.values;
notifyDataSetChanged();
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
items = mOriginalData;
if (constraint.length() == 0 || constraint.equals("")) {
FilterResults original = new FilterResults();
original.count = items.size();
original.values = items;
return original;
} else {
List<Data> filtered = new ArrayList<Data>();
for (Data l : items) {
if ( SOME CONDITION TO FILTER ){ // YOU NEED TO CHANGE THIS
filtered.add(l);
}
}
FilterResults newFilterResults = new FilterResults();
newFilterResults.count = filtered.size();
newFilterResults.values = filtered;
return newFilterResults;
}
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new MyFilter();
}
return mFilter;
}