2011-12-30 127 views
16

我正在開發應用程序,其中有列表和上面的編輯文本,現在我會在editText中鍵入的東西我應該得到匹配的輸入word.bt的結果我不能得到結果,Plz告訴我在哪裏犯錯誤?以下是我的活動和適配器。列表過濾器自定義適配器不給結果

**活動* *

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; 
     } 
    } 

PLZ幫我....

回答

51

您需要實現Filterable你的適配器類別和覆蓋getFilter()

結帳this用於過濾自定義適配器完整的例子。

UPDATE:

 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; 
       } 
      } 
     } 
+1

謝謝,它的工作 – Richa 2011-12-30 11:16:42

+1

@Lalit Poptani +1 Nice answer !!! – Venky 2011-12-30 12:48:43

+1

偉大的@我和我們現在它的工作,謝謝 – Weloo 2012-04-24 14:50:16

2

您需要在您的自定義適配器中覆蓋getFilter()

+0

我已經實現用getFilter(),BT它不給準確result.Canü指寫在適配器的代碼和幫助我嗎? – Richa 2011-12-30 10:38:09

1

雖然拉利特的解決方案完美的作品,可以實現在動作條的搜索查看這使你的UI票友。您可以在活動獲得搜索查看下文提到的 -

@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; 
} 
1
/* 
* 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; 
    } 
} 
相關問題