Инструменты пользователя

Инструменты сайта


android:listview:filter

Android. Custom ListView Filter. ListView в Android представляет собой список, которые можно наблюдать во множестве приложений - тот же Gmail, Twitter и так далее. В простейшем виде список содержит только текстовую информацию, однако, если помимо текста мы хотим отобразить в строке списка что-то еще, то чаще всего класс, отвечающий за показ данного списка приходится кастомизировать. Также зачастую бывает, что в данном списке необходимо что-то найти, например как в приложении контакты, когда по введенным буквам весь список фильтруется и в нем остаются лишь те контакты, которые содержат введенные нами буквы или цифры. Итак, как же это делается?

Итак, код нашего класса.

public class ShopAdapter extends ArrayAdapter<Shop> {
 
	private int layout;
	private Shop[] values;
	private Filter filter = new Filter() {
 
		@Override
		protected FilterResults performFiltering(CharSequence constraint) {
			constraint = constraint.toString().toLowerCase();
			FilterResults result = new FilterResults();
			if (constraint != null && constraint.toString().length() > 0) {
				List<Shop> founded = new ArrayList<Shop>();
				for (Shop t : values) {
					if (t.getAddress().toLowerCase().contains(constraint)
							|| String.valueOf(t.getId()).contains(constraint))
						founded.add(t);
				}
				result.values = founded;
				result.count = founded.size();
			} else {
				result.values = null;
				result.count = 0;
			}
 
			return result;
		}
 
		@Override
		protected void publishResults(CharSequence constraint,
				FilterResults results) {
			clear();
			if (results.values == null) {
				for (Shop o : values) {
					add(o);
				}
			} else {
				for (Shop o : (List<Shop>) results.values) {
					add(o);
				}
			}
			notifyDataSetChanged();
		}
 
	};
 
	public ShopAdapter(Context context, Shop[] values, int layout) {
		super(context, layout, values == null ? new ArrayList<Shop>()
				: new ArrayList<Shop>());
		for (Shop o : values) {
			add(o);
		}
		this.layout = layout;
		this.values = values;
	}
 
	public long getItemId(int position) {
		return getItem(position).getId();
	}
 
	public static void fillView(Activity activity, final Shop item, final View v) {
 
		svUtils.fillTextView(activity, v, R.id.number,
				String.valueOf(item.getId()));
		svUtils.fillTextView(activity, v, R.id.address, item.getAddress());
 
	}
 
	public View getView(int position, View convertView, ViewGroup parent) {
		View v = convertView;
		LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
				Context.LAYOUT_INFLATER_SERVICE);
		v = vi.inflate(layout, null);
 
		Shop item = (Shop) getItem(position);
 
		fillView(null, item, v);
 
		return v;
	}
 
	@Override
	public Filter getFilter() {
		return filter;
	}
}

Начну с того, что класс, отвечающий за список будет наследоваться от класс ArrayAdapter<T>, обычно имплементируя свою реализацию адаптера, достаточно переопределить метод getView, однако, мы на этом не остановимся и переопределим метод getFilter, который будет возвращать класс нашего фильтра для нашей реализации списка. Как видно из кода, внутри класса ShopAdapter определяется еще один внутренний класс Filter, который в свою очередь наследуется от класса android.widget.Filter и реализует два метода. Первый метод отвечает за фильтрацию контента, содержащегося в нашем адаптере, второй метод отвечает за его публикацию. Обратите внимание, что на этапе создания нашего класса-адаптера в конструкторе создается дублирующая коллекция для хранения оригинальных результатов, тех, с которыми адаптер был создан, чтобы в любое время можно было вернуться к полному списку. В методе publishResults происходит очистка основной коллекции класса-адаптера от наших объектов, заполнение его новыми объектами и вызов события, говорящего, что содержимое изменилось и лист пора обновить.

Теперь осталось только подцепить это все в активити, для этого она должна содержать какой-то элемент ввода текста, чаще всего это EditText, к которому добавляется TextChangedListener, выглядит примерно так

filterText.addTextChangedListener(filterTextWatcher);
 
    private TextWatcher filterTextWatcher = new TextWatcher() {
        public void afterTextChanged(Editable s) {}
 
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
 
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            adapter.getFilter().filter(s);
        }
    };

http://gobozov.blogspot.ru/2010/12/android-custom-listview-filter.html

/var/www/source/data/pages/android/listview/filter.txt · Последнее изменение: 2024/02/05 12:40 (внешнее изменение)