2015-09-09 2 views
0

Я хотел добавить функцию поиска, которая фильтрует ListView и покажет только результаты, поэтому я добавил EditText, и я добавил к ней TextWatcher и написал этот код MainActivity.this.adapter.getFilter().filter(cs);, но он не работает, он говорит: «Не удается разрешить метод getFilter» и Я получаю тот факт, что в моем BaseAdapter нет метода getFilter, но я не знаю, как это сделать или что я должен писать, и я увидел пару учебных пособий, но я не могу с ним справиться с моим кодом. PS: ListView элементы собраны из Интернета, они не сохраняются в коде приложенияКак добавить панель поиска для списка?

Вот MainActivity:

public class MainActivity extends Activity { 

private static final String TAG = MainActivity.class.getSimpleName(); 
private DrawerLayout mDrawerLayout; 
private ListView mDrawerList; 
private ActionBarDrawerToggle mDrawerToggle; 
private InterstitialAd interstitial; 

// Navigation drawer title 
private CharSequence mDrawerTitle; 
private CharSequence mTitle; 
private List<Category> albumsList; 
private ArrayList<NavDrawerItem> navDrawerItems; 
private NavDrawerListAdapter adapter; 
private LinearLayout DrawerLinear; 

@SuppressLint("NewApi") 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Log.d("Test", "OnCreate Called"); 

    mTitle = mDrawerTitle = getTitle(); 

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 
    mDrawerList = (ListView) findViewById(R.id.list_slidermenu); 
    DrawerLinear = (LinearLayout) findViewById(R.id.DrawerLinear); 

    navDrawerItems = new ArrayList<NavDrawerItem>(); 

    // Getting the albums from shared preferences 
    albumsList = AppController.getInstance().getPrefManger().getCategories(); 

    // Insert "Recently Added" in navigation drawer first position 
    Category recentAlbum = new Category(null, 
      getString(R.string.nav_drawer_recently_added)); 

    albumsList.add(0, recentAlbum); 

    // Loop through albums in add them to navigation drawer adapter 
    for (Category a : albumsList) { 
     navDrawerItems.add(new NavDrawerItem(a.getId(), a.getTitle())); 
    } 

    mDrawerList.setOnItemClickListener(new SlideMenuClickListener()); 

    // Setting the nav drawer list adapter 
    adapter = new NavDrawerListAdapter(getApplicationContext(), 
      navDrawerItems); 
    mDrawerList.setAdapter(adapter); 

    // Enabling action bar app icon and behaving it as toggle button 
    getActionBar().setDisplayHomeAsUpEnabled(true); 
    getActionBar().setHomeButtonEnabled(true); 
    getActionBar().setIcon(
      new ColorDrawable(getResources().getColor(
        android.R.color.transparent))); 

    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 
      R.drawable.ic_drawer, R.string.app_name, R.string.app_name) { 
     public void onDrawerClosed(View view) { 
      getActionBar().setTitle(mTitle); 
      // calling onPrepareOptionsMenu() to show action bar icons 
      invalidateOptionsMenu(); 
     } 

     public void onDrawerOpened(View drawerView) { 
      getActionBar().setTitle(mDrawerTitle); 
      // calling onPrepareOptionsMenu() to hide action bar icons 
      invalidateOptionsMenu(); 
     } 
    }; 
    mDrawerLayout.setDrawerListener(mDrawerToggle); 

    if (savedInstanceState == null) { 
     // on first time display view for first nav item 
     displayView(0); 
    } 

    final EditText inputSearch = (EditText) findViewById(R.id.inputSearch); 

    inputSearch.addTextChangedListener(new TextWatcher() { 

     @Override 
     public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { 
      // TODO Auto-generated method stub 
      //You should use the adapter in NavigationDrawerFragment 
      MainActivity.this.adapter.getFilter().filter(cs); // Doesn't work, gives an error "Cannot resolve getFilter method" 

     } 

     @Override 
     public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, 
             int arg3) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void afterTextChanged(Editable arg0) { 
      // TODO Auto-generated method stub 

     } 
    }); 

} 

и вот мой адаптер:

public class NavDrawerListAdapter extends BaseAdapter{ 

private Context context; 
private ArrayList<NavDrawerItem> navDrawerItems; 

public NavDrawerListAdapter(Context context, 
     ArrayList<NavDrawerItem> navDrawerItems) { 
    this.context = context; 
    this.navDrawerItems = navDrawerItems; 
} 

@Override 
public int getCount() { 
    return navDrawerItems.size(); 
} 

@Override 
public Object getItem(int position) { 
    return navDrawerItems.get(position); 
} 

@Override 
public long getItemId(int position) { 
    return position; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    if (convertView == null) { 
     LayoutInflater mInflater = (LayoutInflater) context 
       .getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 
     convertView = mInflater.inflate(R.layout.drawer_list_item, null); 
    } 

    TextView txtTitle = (TextView) convertView.findViewById(R.id.title); 

    txtTitle.setText(navDrawerItems.get(position).getTitle()); 

    return convertView; 
} 
} 
+0

У вашего адаптера нет метода, называемого getFilter() .. вам необходимо реализовать это – Wicked161089

+0

ref http: // stackoverflow.com/questions/24769257/custom-listview-adapter-with-filter-android – arun

ответ

3

Вы должны осуществлять интерфейс Filterable в вашем пользовательском адаптере. Он не реализован BaseAdapter.

Edit: Это более полный пример:

public class FiltarableAdapter extends BaseAdapter implements Filterable { 

    // keep the full data here. This is needed to not loose it while filtering 
    private List<SomeObject> originalData; 
    // keep the data you want to show to the user here 
    private List<SomeObject> data; 

    // skip adapter methods 

    // we will use an instance of this to perform the filtering 
    private class AdapterFilter implements Filter { 

     FilterResults performFiltering(CharSequence constraint) { 
      // use the constraint to filter your data in this method and create a list containing the result 
      List<SomeObject> filteredData = ... 
      FilterResults result = new FilterResults(); 
      result.count = filteredData.size(); 
      result.object = filteredData; 
     } 

     void publishResults(CharSequence constraint, Filter.FilterResults results) { 
      // here you get the search results and you should use them to update your UI 
      // for brevity of the example, we just replace the current adapter data with the result object 
      FilterableAdapter.this.data = results.object; 
      FilterableAdapter.this.notifyDataSetChanged(); 
     } 
    } 

    public Filter getFilter() { 
     return new AdapterFilter(); 
    } 
} 

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

Надеюсь, это поможет.

+0

Тогда что мне делать? –

+0

Я обновил свой ответ небольшим примером псевдокода –

+0

Что такое 'result.object'? –

0

Первый вы должны реализовать свой адаптер от фильтруемого

общественного класса NavDrawerListAdapter расширяет BaseAdapter реализует фильтруемых

и переопределить метод getFilter:

@Override 
public Filter getFilter() { 
    return new Filter() { 
     @Override 
     protected FilterResults performFiltering(CharSequence searchText) { 
      //by searchText you should filter here 
      FilterResults result = new FilterResults(); 

      // here your filtering 
      // filling result 

      return result; 
     } 

     @Override 
     protected void publishResults(CharSequence charSequence, FilterResults filterResults) { 

     // here your filterResults 
      clear(); 
      addAll(filterResults.values); 
      notifyDataSetChanged(); 
     } 
    }; 
} 

Второй в вашей деятельности декларировать Объект фильтра

private Filter filter; 

в OnCreate инициализации фильтра:

adapter = new NavDrawerListAdapter(getApplicationContext(), 
     navDrawerItems); 
// getting filter from adapter 
filter = adapter.getFilter(); 

и в вашем OnTextChanged:

@Override 
    public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { 
     // TODO Auto-generated method stub 
     //You should use the adapter in NavigationDrawerFragment 
     filter.filter(cs); 
    } 

Вот и все :)

0

Вы можете добавить SearchView в вашей панели инструментов/ActionBar в порядке чтобы позволить пользователю искать (фильтровать) список. Вот пример (http://javapapers.com/android/android-searchview-action-bar-tutorial/). Затем вы можете фильтровать с помощью адаптера Filterable, который предлагает вам Данаил Алексиев или просто фильтровать источник адаптера и обновлять адаптер снаружи.

Смежные вопросы