过滤列表不会因空结果而改变
Filter list not changing upon empty results
每当筛选列表视图后没有结果时,我希望它消失并在屏幕中央出现一个文本视图。我知道这一切都需要在 if (results.count == 0) {}
之内进行,但是我遇到了一些与布局相关的错误,我不知道如何解决。这 '?'应该表示列表视图片段的布局,但由于代码不在布局 class 中,我不知道需要替换它的内容(同样适用于(this)
在 TextView tv = new TextView(this);
中)。所有相关帮助将不胜感激。
我想要实现的是:
if (results.count == 0) {
1. Make the list invisible
2. Create a text view programmatically and show it
}
ItemListAdapter class
public class ItemListAdapter extends BaseAdapter implements Filterable {
private List<Victoria> mData;
private List<Victoria> mFilteredData;
private LayoutInflater mInflater;
private ItemFilter mFilter;
private ListView mListView;
public ItemListAdapter (List<Victoria> data, Context context) {
mData = data;
mFilteredData = data;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mFilteredData.size();
}
@Override
public String getItem(int position) {
return mFilteredData.get(position).getItem();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_row, parent, false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.item_title);
holder.description = (TextView) convertView.findViewById(R.id.item_description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.title.setText(mFilteredData.get(position).getItem());
holder.description.setText(mFilteredData.get(position).getItemDescription());
return convertView;
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ItemFilter();
}
return mFilter;
}
/**
* View holder
*/
static class ViewHolder {
private TextView title;
private TextView description;
}
/**
* Filter for filtering list items
*/
private class ItemFilter extends Filter {
/**
* Invoked on a background thread. This is where all the filter logic should go
* @param constraint the constraint to filter on
* @return the resulting list after applying the constraint
*/
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (TextUtils.isEmpty(constraint)) {
results.count = mData.size();
results.values = mData;
} else {
//Create a new list to filter on
List<Victoria> resultList = new ArrayList<Victoria>();
for (Victoria str : mData) {
if (str.getItemDescription().toLowerCase().contains(constraint.toString().toLowerCase())) {
resultList.add(str);
}
}
results.count = resultList.size();
results.values = resultList;
}
return results;
}
/**
* Runs on ui thread
* @param constraint the constraint used for the result
* @param results the results to display
*/
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count == 0) {
//Make list invisible
//Make text view visible
notifyDataSetInvalidated();
} else {
mFilteredData = (ArrayList<Victoria>)results.values;
notifyDataSetChanged();
}
}
}
}
FilterListFragment class
public class FilterListFragment extends ListFragment implements SearchView.OnQueryTextListener {
private ItemListAdapter mAdapter;
public FilterListFragment() {
//Required empty constructor
}
public static FilterListFragment newInstance() {
return new FilterListFragment();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_filter_string_list, container, false);
//Tell the system to call onCreateOptionsMenu
setHasOptionsMenu(true);
initialize(view);
return view;
}
List<Victoria> list = new ArrayList<Victoria>();
private void initialize(View view) {
String[] items = getActivity().getResources().getStringArray(R.array.items);
String[] itemDescriptions = getActivity().getResources().getStringArray(R.array.itemDescriptions);
for (int n = 0; n < items.length; n++){
Victoria victoria = new Victoria();
victoria.setID();
victoria.setItem(items[n]);
victoria.setItemDescription(itemDescriptions[n]);
list.add(victoria);
}
mAdapter = new ItemListAdapter(list, getActivity());
setListAdapter(mAdapter);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Set up search view
inflater.inflate(R.menu.menu_search, menu);
MenuItem item = menu.findItem(R.id.search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
searchView.setQueryHint(getResources().getString(R.string.search_query));
}
@Override
public boolean onQueryTextSubmit(String newText) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
mAdapter.getFilter().filter(newText);
return false;
}
}
您不必处理,Android 会为您处理。在 fragment_filter_string_list.xml
中添加代表空视图的 TextView
,id 为 android:id="@android:id/empty"
。 Android 会处理 show/hide 它,具体取决于您 getCount()
的价值。
编辑,
为了实现你想要的,你的 publishResults
应该看起来像
mFilteredData = (ArrayList<Victoria>)results.values;
notifyDataSetChanged();
您可能还想保留一份 mFilteredData
,以便在查询更改或重置时恢复数据集
每当筛选列表视图后没有结果时,我希望它消失并在屏幕中央出现一个文本视图。我知道这一切都需要在 if (results.count == 0) {}
之内进行,但是我遇到了一些与布局相关的错误,我不知道如何解决。这 '?'应该表示列表视图片段的布局,但由于代码不在布局 class 中,我不知道需要替换它的内容(同样适用于(this)
在 TextView tv = new TextView(this);
中)。所有相关帮助将不胜感激。
我想要实现的是:
if (results.count == 0) {
1. Make the list invisible
2. Create a text view programmatically and show it
}
ItemListAdapter class
public class ItemListAdapter extends BaseAdapter implements Filterable {
private List<Victoria> mData;
private List<Victoria> mFilteredData;
private LayoutInflater mInflater;
private ItemFilter mFilter;
private ListView mListView;
public ItemListAdapter (List<Victoria> data, Context context) {
mData = data;
mFilteredData = data;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mFilteredData.size();
}
@Override
public String getItem(int position) {
return mFilteredData.get(position).getItem();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_row, parent, false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.item_title);
holder.description = (TextView) convertView.findViewById(R.id.item_description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.title.setText(mFilteredData.get(position).getItem());
holder.description.setText(mFilteredData.get(position).getItemDescription());
return convertView;
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ItemFilter();
}
return mFilter;
}
/**
* View holder
*/
static class ViewHolder {
private TextView title;
private TextView description;
}
/**
* Filter for filtering list items
*/
private class ItemFilter extends Filter {
/**
* Invoked on a background thread. This is where all the filter logic should go
* @param constraint the constraint to filter on
* @return the resulting list after applying the constraint
*/
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (TextUtils.isEmpty(constraint)) {
results.count = mData.size();
results.values = mData;
} else {
//Create a new list to filter on
List<Victoria> resultList = new ArrayList<Victoria>();
for (Victoria str : mData) {
if (str.getItemDescription().toLowerCase().contains(constraint.toString().toLowerCase())) {
resultList.add(str);
}
}
results.count = resultList.size();
results.values = resultList;
}
return results;
}
/**
* Runs on ui thread
* @param constraint the constraint used for the result
* @param results the results to display
*/
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count == 0) {
//Make list invisible
//Make text view visible
notifyDataSetInvalidated();
} else {
mFilteredData = (ArrayList<Victoria>)results.values;
notifyDataSetChanged();
}
}
}
}
FilterListFragment class
public class FilterListFragment extends ListFragment implements SearchView.OnQueryTextListener {
private ItemListAdapter mAdapter;
public FilterListFragment() {
//Required empty constructor
}
public static FilterListFragment newInstance() {
return new FilterListFragment();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_filter_string_list, container, false);
//Tell the system to call onCreateOptionsMenu
setHasOptionsMenu(true);
initialize(view);
return view;
}
List<Victoria> list = new ArrayList<Victoria>();
private void initialize(View view) {
String[] items = getActivity().getResources().getStringArray(R.array.items);
String[] itemDescriptions = getActivity().getResources().getStringArray(R.array.itemDescriptions);
for (int n = 0; n < items.length; n++){
Victoria victoria = new Victoria();
victoria.setID();
victoria.setItem(items[n]);
victoria.setItemDescription(itemDescriptions[n]);
list.add(victoria);
}
mAdapter = new ItemListAdapter(list, getActivity());
setListAdapter(mAdapter);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Set up search view
inflater.inflate(R.menu.menu_search, menu);
MenuItem item = menu.findItem(R.id.search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(this);
searchView.setQueryHint(getResources().getString(R.string.search_query));
}
@Override
public boolean onQueryTextSubmit(String newText) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
mAdapter.getFilter().filter(newText);
return false;
}
}
您不必处理,Android 会为您处理。在 fragment_filter_string_list.xml
中添加代表空视图的 TextView
,id 为 android:id="@android:id/empty"
。 Android 会处理 show/hide 它,具体取决于您 getCount()
的价值。
编辑,
为了实现你想要的,你的 publishResults
应该看起来像
mFilteredData = (ArrayList<Victoria>)results.values;
notifyDataSetChanged();
您可能还想保留一份 mFilteredData
,以便在查询更改或重置时恢复数据集