【问题标题】:List Filter Custom Adapter dont give result列表过滤器自定义适配器不给出结果
【发布时间】:2011-12-30 09:46:57
【问题描述】:

我正在开发应用程序,其中有列表和上方的编辑文本,当我在 editText 中键入内容时,我应该得到与键入的单词匹配的结果。bt 我无法得到结果,请告诉我我在哪里犯了错误?下面是我的 Activity 和 Adapter。

**活动**

public class ListFilterActivity extends ListActivity{

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

        list = getListView();
        list.isTextFilterEnabled();

//      final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
//                android.R.layout.simple_list_item_1, android.R.id.text1,
//                getModel());
        final CustomAdapter adapter = new CustomAdapter(ListFilterActivity.this, getModel());
        setListAdapter(adapter);
        EditText filterEditText = (EditText) findViewById(R.id.filterText);
        filterEditText.addTextChangedListener(new TextWatcher() {

            public void onTextChanged(CharSequence s, int start, int before,
                    int count) {
                adapter.getFilter().filter(s.toString());
            }

            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {
            }

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

    private ArrayList<String> getModel() {
        ArrayList<String> list = new ArrayList<String>();
        list.add("Linux");
        list.add("Windows7");
        list.add("Suse");
        list.add("Eclipse");
        list.add("Ubuntu");
        list.add("Solaris");
        list.add("Android");
        list.add("Ayes");
        list.add("iPhone");
        return list;
    }



}

适配器***

    public class CustomAdapter extends ArrayAdapter<String> {
        private final Context context;
        private final ArrayList<String> names;
        private LayoutInflater mInflater;
        private TextView txt;

        public CustomAdapter(Context context, ArrayList<String> names) {
            super(context, R.layout.row, names);
            this.context = context;
            this.names = names;
            mInflater =  LayoutInflater.from(context);
        }

public Filter getFilter() {     
        if(newFilter == null) {
            newFilter = new Filter() {
                @Override
                protected void publishResults(CharSequence constraint, FilterResults results) {
                    // TODO Auto-generated method stub
                    Log.d("TAG", "publishResults");
                    notifyDataSetChanged();
                }
                @Override
                protected FilterResults performFiltering(CharSequence prefix) {             

                    FilterResults results = new FilterResults();
                    ArrayList<String> i = new ArrayList<String>();

                    if (prefix!= null && prefix.toString().length() > 0) {

                        for (int index = 0; index < names.size(); index++) {
                            String si = names.get(index);
                            if(si.compareTo(prefix.toString()) == 0){
                                i.add(si);  
                            }
                        }
                        results.values = i;
                        results.count = i.size();                   
                    }
                    else{
                        synchronized (names){
                            results.values = names;
                            results.count = names.size();
                        }
                    }

                    return results;
                }

            };
        }
            //    Log.d("TAG", "end getFilter");
        return newFilter;
    }
@Override
    public String getItem(int position) {    
        return super.getItem(position);
    }

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View rowView  = convertView;
            if(rowView == null) {       
                rowView = mInflater.inflate(R.layout.row, null);
                txt = (TextView)rowView.findViewById(R.id.text1);
            }
            else {
                rowView.getTag();
            }
            txt.setText(names.get(position));

            return rowView;
        }
    }

请帮帮我....

【问题讨论】:

    标签: android


    【解决方案1】:

    您需要在您的适配器类中实现Filterable 并覆盖getFilter()

    Checkout this 过滤自定义适配器的完整示例。

    更新:

          public class ListFilterActivity extends ListActivity {
    
                    private List<String> list = new ArrayList<String>();
                    List<String> mOriginalValues;
    
                    @Override
                    public void onCreate(Bundle savedInstanceState) {
                        super.onCreate(savedInstanceState);
                        setContentView(R.layout.main);
    
                        final MyAdapter adapter = new MyAdapter(this, getModel());
                        setListAdapter(adapter);
    
                        EditText filterEditText = (EditText) findViewById(R.id.filterText);
    
                        // Add Text Change Listener to EditText
                        filterEditText.addTextChangedListener(new TextWatcher() {
    
                            @Override
                            public void onTextChanged(CharSequence s, int start, int before, int count) {
                                // Call back the Adapter with current character to Filter
                                adapter.getFilter().filter(s.toString());
                            }
    
                            @Override
                            public void beforeTextChanged(CharSequence s, int start, int count,int after) {
                            }
    
                            @Override
                            public void afterTextChanged(Editable s) {
                            }
                        });
                    }
    
                    private List<String> getModel() {
                        list.add("Linux");
                        list.add("Windows7");
                        list.add("Suse");
                        list.add("Eclipse");
                        list.add("Ubuntu");
                        list.add("Solaris");
                        list.add("Android");
                        list.add("iPhone");
                        list.add("Windows XP");
                        return list;
                    }
    
        // Adapter Class            
        public class MyAdapter extends BaseAdapter implements Filterable {
    
                    List<String> arrayList;      
                    List<String> mOriginalValues; // Original Values
                    LayoutInflater inflater;
    
                    public MyAdapter(Context context, List<String> arrayList) {
                        this.arrayList = arrayList;
                        inflater = LayoutInflater.from(context);
                    }
    
                    @Override
                    public int getCount() {
                        return arrayList.size();
                    }
    
                    @Override
                    public Object getItem(int position) {
                        return arrayList.get(position);
                    }
    
                    @Override
                    public long getItemId(int position) {
                        return position;
                    }
    
                    private class ViewHolder {
                        TextView textView;
                    }
    
                    @Override
                    public View getView(int position, View convertView, ViewGroup parent) {
    
                        ViewHolder holder = null;
    
                        if (convertView == null) {
    
                            holder = new ViewHolder();
                            convertView = inflater.inflate(R.layout.row, null);
                            holder.textView = (TextView) convertView
                                    .findViewById(R.id.textview);
                            convertView.setTag(holder);
                        } else {
                            holder = (ViewHolder) convertView.getTag();
                        }
                        holder.textView.setText(arrayList.get(position));
                        return convertView;
                    }
    
                    @Override
                    public Filter getFilter() {
                        Filter filter = new Filter() {
    
                            @SuppressWarnings("unchecked")
                            @Override
                            protected void publishResults(CharSequence constraint,FilterResults results) {
    
                                arrayList = (List<String>) results.values; // has the filtered values
                                notifyDataSetChanged();  // notifies the data with new filtered values
                            }
    
                            @Override
                            protected FilterResults performFiltering(CharSequence constraint) {
                                FilterResults results = new FilterResults();        // Holds the results of a filtering operation in values
                                List<String> FilteredArrList = new ArrayList<String>();
    
                                if (mOriginalValues == null) {
                                    mOriginalValues = new ArrayList<String>(arrayList); // saves the original data in mOriginalValues
                                }
    
                                /********
                                 * 
                                 *  If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values
                                 *  else does the Filtering and returns FilteredArrList(Filtered)  
                                 *
                                 ********/
                                if (constraint == null || constraint.length() == 0) {
    
                                    // set the Original result to return  
                                    results.count = mOriginalValues.size();
                                    results.values = mOriginalValues;
                                } else {
                                    constraint = constraint.toString().toLowerCase();
                                    for (int i = 0; i < mOriginalValues.size(); i++) {
                                        String data = mOriginalValues.get(i);
                                        if (data.toLowerCase().contains(constraint.toString())) {
                                            FilteredArrList.add(data);
                                        }
                                    }
                                    // set the Filtered result to return
                                    results.count = FilteredArrList.size();
                                    results.values = FilteredArrList;
                                }
                                return results;
                            }
                        };
                        return filter;
                    }
                }
            }
    

    【讨论】:

    • @Lalit Poptani 我已经尝试过你的代码,但它对我不起作用,我需要你,如果你能帮忙,请告诉我
    • @Lalit Poptani 我的过滤方式相同,但我有一个问题 list.add("Linux");list.add("Windows7");list.add("Linux");list .add("Windows7");意思是我在搜索 Linux 时重复了数据,当我单击第二个数据并从另一个列表视图中查找 id 时,我发现了两个数据,其中我有比较值,所以它会给我第一个列表视图 id,但我想要其他的,所以你能告诉我对此有所了解。
    • 老兄你在吗@Lalit Poptani,我有点怀疑如何根据你的回答修改我的代码
    • @Lalit Poptani 我想过滤 4 个 ArrayList。请帮助任何教程。我也想过滤纬度和经度值Arraylisy。并且必须相应地处理 OnItemCLik Listener。谢谢
    • 最好使用TextUtils.isEmpty()方法,而不是构造if (constraint == null || constraint.length() == 0) {
    【解决方案2】:

    您需要在自定义适配器中覆盖 getFilter()

    【讨论】:

    • 我已经实现了 getFilter(),但它没有给出准确的结果。你能参考适配器中编写的代码并帮助我吗?
    【解决方案3】:

    虽然 Lalit 的解决方案完美运行,但您可以在 ActionBar 中实现 SearchView,让您的 UI 更加精美。如下所述,您可以在活动中获取 SearchView -

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    
        //Create the search view
        SearchView searchView = new SearchView(getSupportActionBar().getThemedContext());
    
        mListView = getListView();
        mListView.setTextFilterEnabled(true);
    
        setupSearchView(searchView);
    
        menu.add(0, 1, 1, "Search Text")
            .setIcon(R.drawable.ic_search)
            .setActionView(searchView)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
    
        return super.onCreateOptionsMenu(menu);
    }
    
    private void setupSearchView(SearchView mSearchView) {
        mSearchView.setIconifiedByDefault(false);
        mSearchView.setSubmitButtonEnabled(false);
        mSearchView.setOnQueryTextListener(this);
        mSearchView.setQueryHint("Search Text");
    }
    
    @Override
    public boolean onQueryTextChange(String newText) {
        if (TextUtils.isEmpty(newText)) {
            mListView.clearTextFilter();
        } else {
            mListView.setFilterText(newText);
        }
        return true;
    }
    
    @Override
    public boolean onQueryTextSubmit(String query) {
        return false;
    }
    

    【讨论】:

      【解决方案4】:
      /*
       * Copyright (C) 2007 The Android Open Source Project
       *
       * Licensed under the Apache License, Version 2.0 (the "License");
       * you may not use this file except in compliance with the License.
       * You may obtain a copy of the License at
       *
       *      http://www.apache.org/licenses/LICENSE-2.0
       *
       * Unless required by applicable law or agreed to in writing, software
       * distributed under the License is distributed on an "AS IS" BASIS,
       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       * See the License for the specific language governing permissions and
       * limitations under the License.
       */
      
      package android.app;
      
      import android.content.Context;
      import android.content.Intent;
      import android.content.pm.ComponentInfo;
      import android.content.pm.PackageManager;
      import android.content.pm.ResolveInfo;
      import android.content.res.Resources;
      import android.graphics.Bitmap;
      import android.graphics.Canvas;
      import android.graphics.Paint;
      import android.graphics.PaintFlagsDrawFilter;
      import android.graphics.PixelFormat;
      import android.graphics.Rect;
      import android.graphics.drawable.BitmapDrawable;
      import android.graphics.drawable.Drawable;
      import android.graphics.drawable.PaintDrawable;
      import android.os.Bundle;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;
      import android.view.Window;
      import android.widget.BaseAdapter;
      import android.widget.Filter;
      import android.widget.Filterable;
      import android.widget.ListView;
      import android.widget.TextView;
      
      import java.util.ArrayList;
      import java.util.Collections;
      import java.util.List;
      
      
      /**
       * Displays a list of all activities which can be performed
       * for a given intent. Launches when clicked.
       *
       */
      public abstract class LauncherActivity extends ListActivity {
          Intent mIntent;
          PackageManager mPackageManager;
          IconResizer mIconResizer;
      
          /**
           * An item in the list
           */
          public static class ListItem {
              public ResolveInfo resolveInfo;
              public CharSequence label;
              public Drawable icon;
              public String packageName;
              public String className;
              public Bundle extras;
      
              ListItem(PackageManager pm, ResolveInfo resolveInfo, IconResizer resizer) {
                  this.resolveInfo = resolveInfo;
                  label = resolveInfo.loadLabel(pm);
                  ComponentInfo ci = resolveInfo.activityInfo;
                  if (ci == null) ci = resolveInfo.serviceInfo;
                  if (label == null && ci != null) {
                      label = resolveInfo.activityInfo.name;
                  }
      
                  if (resizer != null) {
                      icon = resizer.createIconThumbnail(resolveInfo.loadIcon(pm));
                  }
                  packageName = ci.applicationInfo.packageName;
                  className = ci.name;
              }
      
              public ListItem() {
              }
          }
      
          /**
           * Adapter which shows the set of activities that can be performed for a given intent.
           */
          private class ActivityAdapter extends BaseAdapter implements Filterable {
              private final Object lock = new Object();
              private ArrayList<ListItem> mOriginalValues;
      
              protected final IconResizer mIconResizer;
              protected final LayoutInflater mInflater;
      
              protected List<ListItem> mActivitiesList;
      
              private Filter mFilter;
      
              public ActivityAdapter(IconResizer resizer) {
                  mIconResizer = resizer;
                  mInflater = (LayoutInflater) LauncherActivity.this.getSystemService(
                          Context.LAYOUT_INFLATER_SERVICE);
                  mActivitiesList = makeListItems();
              }
      
              public Intent intentForPosition(int position) {
                  if (mActivitiesList == null) {
                      return null;
                  }
      
                  Intent intent = new Intent(mIntent);
                  ListItem item = mActivitiesList.get(position);
                  intent.setClassName(item.packageName, item.className);
                  if (item.extras != null) {
                      intent.putExtras(item.extras);
                  }
                  return intent;
              }
      
              public ListItem itemForPosition(int position) {
                  if (mActivitiesList == null) {
                      return null;
                  }
      
                  return mActivitiesList.get(position);
              }
      
              public int getCount() {
                  return mActivitiesList != null ? mActivitiesList.size() : 0;
              }
      
              public Object getItem(int position) {
                  return position;
              }
      
              public long getItemId(int position) {
                  return position;
              }
      
              public View getView(int position, View convertView, ViewGroup parent) {
                  View view;
                  if (convertView == null) {
                      view = mInflater.inflate(
                              com.android.internal.R.layout.activity_list_item_2, parent, false);
                  } else {
                      view = convertView;
                  }
                  bindView(view, mActivitiesList.get(position));
                  return view;
              }
      
              private void bindView(View view, ListItem item) {
                  TextView text = (TextView) view;
                  text.setText(item.label);
                  if (item.icon == null) {
                      item.icon = mIconResizer.createIconThumbnail(
                              item.resolveInfo.loadIcon(getPackageManager()));
                  }
                  text.setCompoundDrawablesWithIntrinsicBounds(item.icon, null, null, null);
              }
      
              public Filter getFilter() {
                  if (mFilter == null) {
                      mFilter = new ArrayFilter();
                  }
                  return mFilter;
              }
      
              /**
               * An array filters constrains the content of the array adapter with a prefix. Each
               * item that does not start with the supplied prefix is removed from the list.
               */
              private class ArrayFilter extends Filter {
                  @Override
                  protected FilterResults performFiltering(CharSequence prefix) {
                      FilterResults results = new FilterResults();
      
                      if (mOriginalValues == null) {
                          synchronized (lock) {
                              mOriginalValues = new ArrayList<ListItem>(mActivitiesList);
                          }
                      }
      
                      if (prefix == null || prefix.length() == 0) {
                          synchronized (lock) {
                              ArrayList<ListItem> list = new ArrayList(mOriginalValues);
                              results.values = list;
                              results.count = list.size();
                          }
                      } else {
                          final String prefixString = prefix.toString().toLowerCase();
      
                          ArrayList<ListItem> values = mOriginalValues;
                          int count = values.size();
      
                          ArrayList<ListItem> newValues = new ArrayList(count);
      
                          for (int i = 0; i < count; i++) {
                              ListItem item = values.get(i);
      
                              String[] words = item.label.toString().toLowerCase().split(" ");
                              int wordCount = words.length;
      
                              for (int k = 0; k < wordCount; k++) {
                                  final String word = words[k];
      
                                  if (word.startsWith(prefixString)) {
                                      newValues.add(item);
                                      break;
                                  }
                              }
                          }
      
                          results.values = newValues;
                          results.count = newValues.size();
                      }
      
                      return results;
                  }
      
                  @Override
                  protected void publishResults(CharSequence constraint, FilterResults results) {
                      //noinspection unchecked
                      mActivitiesList = (List<ListItem>) results.values;
                      if (results.count > 0) {
                          notifyDataSetChanged();
                      } else {
                          notifyDataSetInvalidated();
                      }
                  }
              }
          }
      
          /**
           * Utility class to resize icons to match default icon size.  
           */
          public class IconResizer {
              // Code is borrowed from com.android.launcher.Utilities. 
              private int mIconWidth = -1;
              private int mIconHeight = -1;
      
              private final Rect mOldBounds = new Rect();
              private Canvas mCanvas = new Canvas();
      
              public IconResizer() {
                  mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
                          Paint.FILTER_BITMAP_FLAG));
      
                  final Resources resources = LauncherActivity.this.getResources();
                  mIconWidth = mIconHeight = (int) resources.getDimension(
                          android.R.dimen.app_icon_size);
              }
      
              /**
               * Returns a Drawable representing the thumbnail of the specified Drawable.
               * The size of the thumbnail is defined by the dimension
               * android.R.dimen.launcher_application_icon_size.
               *
               * This method is not thread-safe and should be invoked on the UI thread only.
               *
               * @param icon The icon to get a thumbnail of.
               *
               * @return A thumbnail for the specified icon or the icon itself if the
               *         thumbnail could not be created. 
               */
              public Drawable createIconThumbnail(Drawable icon) {
                  int width = mIconWidth;
                  int height = mIconHeight;
      
                  final int iconWidth = icon.getIntrinsicWidth();
                  final int iconHeight = icon.getIntrinsicHeight();
      
                  if (icon instanceof PaintDrawable) {
                      PaintDrawable painter = (PaintDrawable) icon;
                      painter.setIntrinsicWidth(width);
                      painter.setIntrinsicHeight(height);
                  }
      
                  if (width > 0 && height > 0) {
                      if (width < iconWidth || height < iconHeight) {
                          final float ratio = (float) iconWidth / iconHeight;
      
                          if (iconWidth > iconHeight) {
                              height = (int) (width / ratio);
                          } else if (iconHeight > iconWidth) {
                              width = (int) (height * ratio);
                          }
      
                          final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ?
                                      Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
                          final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
                          final Canvas canvas = mCanvas;
                          canvas.setBitmap(thumb);
                          // Copy the old bounds to restore them later
                          // If we were to do oldBounds = icon.getBounds(),
                          // the call to setBounds() that follows would
                          // change the same instance and we would lose the
                          // old bounds
                          mOldBounds.set(icon.getBounds());
                          final int x = (mIconWidth - width) / 2;
                          final int y = (mIconHeight - height) / 2;
                          icon.setBounds(x, y, x + width, y + height);
                          icon.draw(canvas);
                          icon.setBounds(mOldBounds);
                          icon = new BitmapDrawable(getResources(), thumb);
                      } else if (iconWidth < width && iconHeight < height) {
                          final Bitmap.Config c = Bitmap.Config.ARGB_8888;
                          final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
                          final Canvas canvas = mCanvas;
                          canvas.setBitmap(thumb);
                          mOldBounds.set(icon.getBounds());
                          final int x = (width - iconWidth) / 2;
                          final int y = (height - iconHeight) / 2;
                          icon.setBounds(x, y, x + iconWidth, y + iconHeight);
                          icon.draw(canvas);
                          icon.setBounds(mOldBounds);
                          icon = new BitmapDrawable(getResources(), thumb);
                      }
                  }
      
                  return icon;
              }
          }
      
          @Override
          protected void onCreate(Bundle icicle) {
              super.onCreate(icicle);
      
              mPackageManager = getPackageManager();
      
              requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
              setProgressBarIndeterminateVisibility(true);
              onSetContentView();
      
              mIconResizer = new IconResizer();
      
              mIntent = new Intent(getTargetIntent());
              mIntent.setComponent(null);
              mAdapter = new ActivityAdapter(mIconResizer);
      
              setListAdapter(mAdapter);
              getListView().setTextFilterEnabled(true);
      
              setProgressBarIndeterminateVisibility(false);
          }
      
          /**
           * Override to call setContentView() with your own content view to
           * customize the list layout.
           */
          protected void onSetContentView() {
              setContentView(com.android.internal.R.layout.activity_list);
          }
      
          @Override
          protected void onListItemClick(ListView l, View v, int position, long id) {
              Intent intent = intentForPosition(position);
              startActivity(intent);
          }
      
          /**
           * Return the actual Intent for a specific position in our
           * {@link android.widget.ListView}.
           * @param position The item whose Intent to return
           */
          protected Intent intentForPosition(int position) {
              ActivityAdapter adapter = (ActivityAdapter) mAdapter;
              return adapter.intentForPosition(position);
          }
      
          /**
           * Return the {@link ListItem} for a specific position in our
           * {@link android.widget.ListView}.
           * @param position The item to return
           */
          protected ListItem itemForPosition(int position) {
              ActivityAdapter adapter = (ActivityAdapter) mAdapter;
              return adapter.itemForPosition(position);
          }
      
          /**
           * Get the base intent to use when running
           * {@link PackageManager#queryIntentActivities(Intent, int)}.
           */
          protected Intent getTargetIntent() {
              return new Intent();
          }
      
          /**
           * Perform query on package manager for list items.  The default
           * implementation queries for activities.
           */
          protected List<ResolveInfo> onQueryPackageManager(Intent queryIntent) {
              return mPackageManager.queryIntentActivities(queryIntent, /* no flags */ 0);
          }
      
          /**
           * Perform the query to determine which results to show and return a list of them.
           */
          public List<ListItem> makeListItems() {
              // Load all matching activities and sort correctly
              List<ResolveInfo> list = onQueryPackageManager(mIntent);
              Collections.sort(list, new ResolveInfo.DisplayNameComparator(mPackageManager));
      
              ArrayList<ListItem> result = new ArrayList(list.size());
              int listSize = list.size();
              for (int i = 0; i < listSize; i++) {
                  ResolveInfo resolveInfo = list.get(i);
                  result.add(new ListItem(mPackageManager, resolveInfo, null));
              }
      
              return result;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多