Фильтрация списка не работает - Android

Я привязываюсь к реализации функции поиска в своем приложении. Я использую пользовательский ArrayAdapter<String> для listview, так как у меня есть два textViews подряд. Мое приложение не закрывается принудительно, но поиск не работает должным образом. Он не фильтрует представление списка, но когда я набираю что-то, чего нет в представлении списка, он правильно показывает страницу, на которой нет найденных элементов. Что могло быть не так? Вот код. Пожалуйста, наведите меня на правильный путь!

MainActivity.java

public class MainActivity extends Activity {
final String[] elename ={"Hydrogen","Helium","Lithium","Beryllium","Boron","Carbon","Nitrogen","Oxygen","Fluorine","Neon","Sodium","Magnesium","Aluminium","Silicon","Phosphorous","Sulphur","Chlorine","Argon","Potassium","Calcium","Scandium","Titanium","Vanadium","Chromium","Manganese","Iron","Cobalt","Nickel","Copper","Zinc","Gallium","Germanium","Arsenic","Selenium","Bromine","Krypton","Rubidium","Strontium","Yttrium","Zirconium","Niobium","Molybdenum","Technetium","Ruthenium","Rhodium","Palladium","Silver","Cadmium","Indium","Tin","Antimony","Tellurium","Iodine","Xenon","Caesium","Barium","Lanthanum","Cerium","Praseodymium","Neodymium","Promethium","Samarium","Europium","Gadolinium","Terbium","Dysprosium","Holmium","Erbium","Thulium","Ytterbium","Lutetium","Hafnium","Tantalum","Tungsten","Rhenium","Osmium","Iridium","Platinum","Gold","Mercury","Thallium","Lead","Bismuth","Polonium","Astatine","Radon","Francium","Radium","Actinium","Thorium","Protactinium","Uranium","Neptunium","Plutonium","Americium","Curium","Berkelium","Californium","Einsteinium","Fermium","Mendelevium","Nobelium","Lawrencium","Rutherfordium","Dubnium","Seaborgium","Bohrium","Hassium","Meitnerium","Darmstadtium","Roentgenium","Copernicium","Ununtrium","Ununquadium","Ununpentium","Ununhexium","Ununseptium","Ununoctium"};
final String[] nos = {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59","60","61","62","63","64","65","66","67","68","69","70","71","72","73","74","75","76","77","78","79","80","81","82","83","84","85","86","87","88","89","90","91","92","93","94","95","96","97","98","99","100","101","102","103","104","105","106","107","108","109","110","111","112","113","114","115","116","117","118"};
CustomAdapter cus;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final EditText searchBar = (EditText) findViewById(R.id.searchbar);
    final DrawerLayout drawer = (DrawerLayout)findViewById(R.id.drawer_layout);
    final ListView navList = (ListView) findViewById(R.id.left_drawer);
    final LinearLayout linearLayout = (LinearLayout)findViewById(R.id.left_drawer_layout);
    cus = new CustomAdapter(MainActivity.this,elename,nos);
    navList.setAdapter(cus);


    navList.setOnItemClickListener(new AdapterView.OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> parent, View view, final int pos,long id){
            //Change view according to numbers

            drawer.closeDrawer(linearLayout);
        }
    });

    //filter list view after search instantly
    searchBar.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
            // When user changed the Text
            MainActivity.this.cus.getFilter().filter(cs);
        }

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,int arg3) {

        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });

    //hide the keyboard after search on touch list view
    navList.setOnScrollListener(new AbsListView.OnScrollListener() {
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            //hide keyboard
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(navList.getWindowToken(), 0);
        }

        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        }
    });

    navList.setEmptyView(findViewById(R.id.empty));

}
}

CustomAdapter.java

class CustomAdapter extends ArrayAdapter<String>
{
String A[],B[];
LayoutInflater mInflater;
public CustomAdapter(Context context, String[] A,String B[])
{
    super(context,R.layout.list_item,A);
    this.A = A;
    this.B = B;
    mInflater = LayoutInflater.from(context);
}
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if(convertView==null)
    {
        convertView = mInflater.inflate(R.layout.list_item,parent,false);
        holder = new ViewHolder();
        holder.tv1 = (TextView)convertView.findViewById(R.id.element_name);
        holder.tv2 = (TextView)convertView.findViewById(R.id.element_nos);
        convertView.setTag(holder);
    }else{
        holder = (ViewHolder)convertView.getTag();
    }

    holder.tv1.setText(A[position]);
    holder.tv2.setText(B[position]);
    return convertView;
}
static class ViewHolder
{
    TextView tv1,tv2;
}
}

РЕДАКТИРОВАТЬ: принудительное закрытие приложения после реализации интерфейса.

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.Chinmay.navigationdrawer/com.Chinmay.navigationdrawer.MainActivity}: java.lang.ClassCastException: com.Chinmay.navigationdrawer.MainActivity
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3687)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.ClassCastException: com.Chinmay.navigationdrawer.MainActivity
    at com.Chinmay.navigationdrawer.MainActivity.onCreate(MainActivity.java:49)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)

person user3234390    schedule 27.01.2014    source источник
comment
Взгляните на этот ответ. Это может помочь.   -  person Emmanuel    schedule 27.01.2014
comment
на каком основании вы хотите, чтобы поиск происходил?   -  person Raghunandan    schedule 27.01.2014
comment
@Raghunndan поиск будет искать String elename и мгновенно фильтровать его по мере ввода!   -  person user3234390    schedule 27.01.2014
comment
@ user3234390 извините, разместил неверную ссылку. проверьте этот заголовок stackoverflow.com/questions/13090046/, и я предполагаю, что вы тот пользователь, который задавал вопросы о панели навигации.   -  person Raghunandan    schedule 27.01.2014
comment
если у вас есть две строки для отображения в каждом iten, не используйте String в качестве универсального типа для ArrayAdapter, используйте класс, содержащий эти два Steings   -  person pskink    schedule 27.01.2014


Ответы (2)


Добавьте это cus.setSearchFilterItemListener(this); перед navList.setAdapter(cus);

Обновить

Шаг 1 Создайте интерфейс

public interface SearchFilterItemListener {

    public void setData(String[] myArray);
}

Шаг 2. Обновите собственный класс адаптера.

class CustomAdapter extends ArrayAdapter<String> {
    String A[], B[], origA[], origB[];
    LayoutInflater mInflater;

public CustomAdapter(Context context, String[] A,String B[]) {
    super(context, R.layout.list_item, A);
    this.A = A;
    this.B = B;
    this.origA = A;
    this.origB = B;
    mInflater = LayoutInflater.from(context);
}

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if(convertView == null) {
        convertView = mInflater.inflate(R.layout.list_item, parent, false);
        holder = new ViewHolder();
        holder.tv1 = (TextView)convertView.findViewById(R.id.element_name);
        holder.tv2 = (TextView)convertView.findViewById(R.id.element_nos);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder)convertView.getTag();
    }

    holder.tv1.setText(A[position]);
    holder.tv2.setText(B[position]);
    return convertView;
}

static class ViewHolder {
    TextView tv1,tv2;
}

@Override
public Filter getFilter() {
    if (listFilter == null)
        listFilter = new TabFilter();
    return listFilter;
}

private class TabFilter extends Filter {

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        // TODO Auto-generated method stub
        FilterResults results = new FilterResults();
        // Filter Logic
        if (constraint == null || constraint.length() == 0) {
            // No filter, return all the list
            results.values = origA; //considering that you want to filter on the String[] A
            results.count = origA.size();
        } else {
            // We perform filtering operation
            String[] nList = new String[A.length];

            for (int counter = 0; counter < A.length; counter++) {
                if (A[counter].toUpperCase(Locale.US).startsWith(constraint.toString().toUpperCase(Locale.US)))
                    nList[counter] = A[counter];
            }
            results.values = nList;
            results.count = nList.length;
        }

        return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        // TODO Auto-generated method stub
        // Now we have to inform the adapter about the new filtered list
        if (results.count == 0)
            notifyDataSetInvalidated();
        else {
            A = (String[]) results.values;
            String[] newList = new String[A.length];
            newList = A.clone();

            notifyDataSetChanged();

            mSearchListener.setData(newList);
        }
    }
}

public String[] getSearchList() {
    return A;
}

public void setSearchFilterItemListener(SearchFilterItemListener mSearchFilterListener) {

    mSearchListener = mSearchFilterListener;
}

}

person VikramV    schedule 27.01.2014
comment
показывает ошибку: could not resolve method (cus.setSearchFilterItemListener(this)) - person user3234390; 27.01.2014
comment
Проверьте мой обновленный ответ !! Приносим извинения за причиненные неудобства. - person VikramV; 27.01.2014
comment
в какой файл поместить интерфейс? Я новичок, поэтому не знаю о них. пожалуйста, простите меня, если это глупый вопрос, сэр! - person user3234390; 27.01.2014
comment
его принудительное закрытие после того, как я реализую ваш код, сэр. пожалуйста, взгляните на мой вопрос! - person user3234390; 27.01.2014
comment
Я не понял, что такое mSearchListener и listFilter, и это показывает, что не удалось разрешить оба символа. Также нельзя разрешить метод origA.size(). Пожалуйста помоги! - person user3234390; 27.01.2014
comment
Объявите это в своем адаптере private SearchFilterItemListener mSearchListener; и замените origA.size() на origA.length. - person VikramV; 27.01.2014

хорошо, так что это ваш адаптер:

class CustomAdapter extends ArrayAdapter<Item> {
    LayoutInflater mInflater;
    public CustomAdapter(Context context) {
        super(context, 0);
        mInflater = LayoutInflater.from(context);
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if(convertView == null) {
            convertView = mInflater.inflate(android.R.layout.simple_expandable_list_item_2, parent, false);
            holder = new ViewHolder();
            holder.tv1 = (TextView)convertView.findViewById(android.R.id.text1);
            holder.tv2 = (TextView)convertView.findViewById(android.R.id.text2);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }

        Item item = getItem(position);
        holder.tv1.setText(item.text1);
        holder.tv2.setText(item.text2);
        return convertView;
    }
}

теперь у вас есть класс Item, содержащий две строки:

class Item {
    String text1;
    String text2;
    Item(String t1, String t2) {
        text1 = t1;
        text2 = t2;
    }
    @Override
    public String toString() {
        return text1;
    }
}

и ViewHolder:

class ViewHolder {
    TextView tv1, tv2;
}

теперь проверьте это в onCreate (попробуйте нажать любую букву, например «p», чтобы отфильтровать элементы, начинающиеся с «p»:

CustomAdapter adapter = new CustomAdapter(this);
for (int i = 0; i < elename.length; i++) {
    adapter.add(new Item(elename[i], nos[i]));
}
lv = new ListView(this);
lv.setTextFilterEnabled(true);
lv.setAdapter(adapter);
setContentView(lv);
person pskink    schedule 27.01.2014
comment
какая-то проблема с методом adapter.add. - person user3234390; 27.01.2014
comment
он говорит, что java.lang.string в arrayadapter не может быть применен, а для строки Item item = getItem(position); он говорит о несовместимых типах. - person user3234390; 27.01.2014
comment
Извините, в onCreate нет проблем, но в строке Item item = getItem(position); говорится о несовместимых типах - person user3234390; 27.01.2014
comment
в строках: holder.tv1.setText(item.text1); holder.tv2.setText(item.text2); is item = Item? и когда я меняю это, он говорит, что не может разрешить метод и символ. - person user3234390; 27.01.2014
comment
Также есть Item = ClipData.Item? потому что он говорит о несовместимых типах: Требуется: com.Chinmay.navigationdrawer.CustomAdapter.Item Найдено: android.Content.ClipData.Item. - person user3234390; 27.01.2014
comment
Я объясню сценарий четко: строка Item item = getItem(position); дает несовместимые типы ошибок. Когда я меняю его на ClipData.Item item = getItem(position);, две строки под ним дают ошибку, которая не может разрешить метод и не может разрешить символ. Пожалуйста, помогите мне. - person user3234390; 27.01.2014
comment
точно! Я не знаю, что такое clipdata! Получил из предложений. Сама строка class CustomAdapter extends ArrayAdapter<Item> показывает следующую ошибку: не удается найти символ класса даже после добавления класса Item. - person user3234390; 27.01.2014
comment
еще раз: добавьте класс элемента, который я опубликовал в ответе - person pskink; 27.01.2014
comment
пожалуйста, разместите окончательный код, чтобы было проще! и проблема не устранена! - person user3234390; 27.01.2014