Intereting Posts
Android: проблема с перетаскиванием Как установить пусковую установку по умолчанию в сборку AOSP? Невозможно называть definVisibility () – никогда не видел подключения для pid – не переходить на страницу Html Библиотека Android с использованием основных ресурсов проекта Есть ли проблемы в веб-обозревателе Android для SVG? Уровень API16 + Масштабируемый список не прокручивается Проблема с производительностью мобильных приложений Javascript API Google Maps Как добавить заголовок и нижний колонтитул к каждой активности в android Как добавить проект Guava в Eclipse File.mkdir () и mkdirs () создают файл вместо каталога Android: HTTPClient Android – как создать диаграмму семейного дерева (визуальный) Как использовать значки и символы из «Font Awesome» в приложении для Android Как правильно использовать предварительно загруженную базу данных в Android Проблемы с визуализацией пользовательского интерфейса Android – Отсутствует библиотека

AddTextChangedListener с listview с подтекстом

Я хочу выполнить поиск по списку и снова отобразить результат в списке, поэтому я использовал addtextchangelistener, но не могу найти способ заставить его работать с listview с подтекстом

Вот мой код:

package com.android; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import android.app.ListActivity; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.View; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; public class MyListDemoActivity extends ListActivity { /** Called when the activity is first created. */ TextView tv; //** List<String> content; EditText actv; List<String> arr_sort; //** ArrayAdapter<String> adapter; SimpleAdapter simpleadapter; ListView lv; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String line = " "; LineNumberReader linenoreader = null; StringTokenizer stringtokanixer = null; //** content = new ArrayList<String>(); List<Map<String,String>> data= new ArrayList<Map<String,String>>(); lv = (ListView) findViewById(android.R.id.list); try { InputStream istream = getResources().openRawResource(R.raw.grelist); InputStreamReader streamreader = new InputStreamReader(istream); linenoreader = new LineNumberReader(streamreader); linenoreader.mark(15); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }// try catch ends here Log.v("getting", "working"); for(int i=0;i<8;i++) { Map<String,String> datum= new HashMap<String,String>(2); try { line = linenoreader.readLine(); Log.v("item",line); } catch (IOException e) { e.printStackTrace(); } Log.v("getting", line); stringtokanixer = new StringTokenizer(line); String st = stringtokanixer.nextToken(); String meaning=""; while (stringtokanixer.hasMoreTokens()) { meaning +=" " +stringtokanixer.nextToken(); }// for ends // map is used to add word and meaning datum.put("word",st); datum.put("meaning",meaning); data.add(datum); //List<String> is usedto add //** content.add(st); } simpleadapter = new SimpleAdapter(this, data, android.R.layout.simple_list_item_2, new String[]{"word","meaning"}, new int[]{android.R.id.text1,android.R.id.text2}); // setListAdapter(adapter); lv.setAdapter(simpleadapter); tv = (TextView) findViewById(R.id.textView1); actv = (EditText) findViewById(R.id.editText1); /* actv.addTextChangedListener(new TextWatcher() { int len = 0; @Override public void onTextChanged(CharSequence s, int start, int before, int count) { arr_sort = new ArrayList<String>(); len = actv.getText().length(); for (int i = 0; i < content.size(); i++) { if (len <= content.get(i).length()) { if (actv.getText() .toString() .trim() .equalsIgnoreCase( (String) content.get(i).subSequence(0, len))) { arr_sort.add(content.get(i)); Log.v("infor loop afterTextChanged", s.toString()); } } } // adapter.notifyDataSetChanged(); adapter = new ArrayAdapter<String>(MyListDemoActivity.this, android.R.layout.simple_list_item_1, arr_sort); setListAdapter(adapter); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { Log.v("beforetextchange","hello here"); } @Override public void afterTextChanged(Editable s) { Log.v("aftertextchange","hello here"); } }); // text watcher class ends here */ }// on create ends here public void onListItemClick(ListView ls, View v, int position, long id) { //tv.setText(content.get(position)); // tv.setText(content[position]) // in case of string }// endsd here onListItemClick( } 

Вот как я изменил бы свой код, чтобы он работал:

1. Я бы arr_sort переменную arr_sort и добавлял другой ArrayList Maps для хранения отфильтрованных значений:

 // List<String> arr_sort; final ArrayList<Map<String, String>> data = new ArrayList<Map<String, String>>(); final ArrayList<Map<String, String>> filteredData = new ArrayList<Map<String, String>>(); 

Я бы также сделал их окончательными, так как нет смысла назначать им совершенно новые значения, пока мы можем изменять их содержимое.

2. simpleadapter всегда должен отображать отфильтрованные данные, поэтому его необходимо изменить:

 filteredData.addAll(data); // fill up filteredData initially with the whole list simpleadapter = new SimpleAdapter(this, filteredData, android.R.layout.simple_list_item_2, new String[] { "word", "meaning" }, new int[] {android.R.id.text1, android.R.id.text2 }); 

3. Затем я переместил код фильтрации из метода onTextChanged метод afterTextChanged , чтобы выполнить фильтрацию на основе всего введенного текста. Использование Regexp также меньше ресурсов, чем все манипуляции с строками (+, подстрока …)

Таким образом, ваша реализация TextWatcher будет выглядеть так:

 actv.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) {} @Override public void beforeTextChanged(CharSequence s,int start,int count,int after) {} @Override public void afterTextChanged(Editable s) { Log.v("MLDA", "afterTextChanged"); // a temporary source list for better performance: // if it's possible, use the smaller filtered list final ArrayList<Map<String, String>> tmpSource = new ArrayList<Map<String,String>>(); tmpSource.addAll( (filterText.length() > 0 && s.toString().contains(filterText)) ? filteredData : data); filterText = s.toString(); // a temporary result list to fill with the filtered data final ArrayList<Map<String, String>> tmpResult = new ArrayList<Map<String,String>>(); if (filterText.length() == 0) tmpResult.addAll(data); //if no filter, return the base data else { final Pattern pattern = Pattern.compile("(?i)" + Pattern.quote(s.toString())); Matcher matcher; for (final Map<String, String> map : tmpSource) { //first match against the "word": matcher = pattern.matcher(map.get("word")); if (!matcher.find()) { //if no matches were found, try to match the "meaning" matcher = pattern.matcher(map.get("meaning")); if (!matcher.find()) continue; //if no match, move to the next map } tmpResult.add(map); //match found: add to new list } } filteredData.clear(); filteredData.addAll(tmpResult); simpleadapter.notifyDataSetChanged(); // update display } }); 

Работа с временными списками позволяет вам создавать все отфильтрованные данные без обновлений gui (при удалении / добавлении элементов в список filteredData напрямую, адаптер инициирует методы обновления).

Также обратите внимание, что, исследуя, содержит ли новый текст фильтра старый, мы можем использовать текущий список filteredData как источник.

Аналогично, если filterText является пустой строкой, нет смысла выполнять какие-либо совпадения, мы можем просто вернуть base список.

Я уже ответил на два вопроса StackOverflow, что вы можете им,

Сначала используется getFilter() который андроид обеспечивает фильтрацию с использованием фильтруемого интерфейса для класса адаптера. Вы можете проверить это here .

Во-вторых, используется внешний банку Lambdaj который является лучшим и эффективным способом фильтрации огромных данных из списка. Вы также можете проверить это here .

Я понял: – Просто вы хотите отфильтровать ListView . Правильно?

Дайте мне знать Если я неправильно понял вопрос !!!

main.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <EditText android:id="@+id/search" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="text" /> <ListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> 

ListViewSearchActivity

 import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.widget.EditText; import android.widget.ListView; import android.widget.SimpleAdapter; public class ListViewSearchActivity extends Activity implements TextWatcher { private SimpleAdapter simpleAdapter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); EditText search = (EditText) findViewById(R.id.search); search.addTextChangedListener(this); List<Map<String, String>> data = new ArrayList<Map<String, String>>(); for(int i=0;i<8;i++) { Map<String,String> map = new HashMap<String, String>(2); map.put("word", "word " + i); map.put("meaning", "meaning " + (i + 10)); data.add(map); } ListView listView = (ListView) findViewById(R.id.list); this.simpleAdapter = new SimpleAdapter(this, data, android.R.layout.simple_list_item_2, new String[]{"word","meaning"}, new int[]{android.R.id.text1,android.R.id.text2}); listView.setAdapter(this.simpleAdapter); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { this.simpleAdapter.getFilter().filter(s.toString()); } } 
 ArrayList<String> tempList ; edtText.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { // TODO Auto-generated method stub } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO Auto-generated method stub } @Override public void afterTextChanged(Editable s) { // TODO Auto-generated method stub if (!edtText.getText().toString().equalsIgnoreCase("")){ tempList = new ArrayList<String>(); tempList.clear(); String text = filterText.getText().toString(); for(int i=0 ;i< listname.size();i++){ //if(globalconstant.mosq_list.get(globalconstant.hashformosq.get(globalconstant.tempList.get(i))).name.toUpperCase().toString().contains(text.toUpperCase())){ if(listname.get(i).toUpperCase().toString().contains(text.toUpperCase())){ tempList.add(listname.get(i)); } } used changed tempList }else{ unchaged tempList } } }); }