Filtering ListView with custom (object) adapter

本文介绍如何为自定义对象的Android ListView实现搜索过滤功能。通过监听EditText的文本变化,使用自定义适配器过滤ListView的数据源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

I'm trying to implement filtering of a ListView which is uses a custom object adapter, but I can't find any useful samples. The included code is very simplified, so no- keep in mind I can't use an regular ArrayAdapter. I have a EditText above the ListView, and when the user enters text in the EditText widget I would like to filter the ListView by the text written in the EditText. Any suggestions would be much appreciated!

Here is the snippet from the activity class:

public class management_objects extends Activity {

private static List<User> UserList;
private EfficientAdapter adapter = null;
private ListView objectListView = null;
private EditText SearchText = null;

private static class EfficientAdapter extends BaseAdapter implements Filterable{
    private LayoutInflater mInflater;   

    public EfficientAdapter(Context context) {
        mInflater = LayoutInflater.from(context);
    }

    public int getCount() {
        return UserList.size();
    }

    public Object getItem(int position) {
        return position;
    }

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

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder; 
        if (convertView == null) { 
            convertView = mInflater.inflate(R.layout.imagelayout_2lines, null);
            holder = new ViewHolder();
            holder.text = (TextView) convertView.findViewById(R.id.managementObjectText);
            holder.subtext = (TextView) convertView.findViewById(R.id.managementObjectSubText);
            holder.icon = (ImageView) convertView.findViewById(R.id.managementObjectIcon);
            convertView.setTag(holder);
        }
        else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.text.setText(UserList.get(position).getFirstName());
        holder.subtext.setText(UserList.get(position).getLastName());
        holder.icon.setImageResource(R.drawable.user);

        return convertView;
    }

    static class ViewHolder { 
        TextView text;
        TextView subtext;
        ImageView icon;
    }

    @Override
    public Filter getFilter() {
        return null;
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.adobjectlist);
    Bundle extras = getIntent().getExtras();

    SearchText = (EditText) findViewById(R.id.SearchBox);    
    SearchText.addTextChangedListener(filterTextWatcher);

    objectListView = (ListView) findViewById(R.id.ObjectList);
    objectListView.setOnItemClickListener(Item_Click);
    adapter = new EfficientAdapter(this);
    ComputerName = extras.getString("COMPUTER_NAME");

    //Get User list from webservice
    ShowUsers();
}

Here is The User class:

 public class User {
  private int UserId;
  private String FirstName;
  private String LastName;

    public int getUserId() {
        return UserId;
    }
    public void setUserId(int UserId) {
        this.UserId = UserId;
    }
    public String getFirstName() {
        return FirstName;
    }
    public void setFirstName(String FirstName) {
        this.FirstName = FirstName;
    }
    public String getLastName() {
        return LastName;
    }
    public void setLastName(String LastName) {
        this.LastName = LastName;
    }
}
share | improve this question
   

2 Answers

You need to do a few things:

1) In your activity, register for a text change listener on your EditText that contains the value the user enters:

mSearchValue.addTextChangedListener(searchTextWatcher);

2) Create your searchTextWatcher and have it do something:

private TextWatcher searchTextWatcher = new TextWatcher() {
    @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // ignore
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            // ignore
        }

        @Override
        public void afterTextChanged(Editable s) {
            Log.d(Constants.TAG, "*** Search value changed: " + s.toString());
            adapter.getFilter().filter(s.toString());
        }
    };

3) Override getFilter() in your custom adapter and have it filter the results and notify the listview that the dataset has changed.

    @Override
    public Filter getFilter() {
        return new Filter() {
            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                Log.d(Constants.TAG, "**** PUBLISHING RESULTS for: " + constraint);
                myData = (List<MyDataType>) results.values;
                MyCustomAdapter.this.notifyDataSetChanged();
            }

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                Log.d(Constants.TAG, "**** PERFORM FILTERING for: " + constraint);
                List<MyDataType> filteredResults = getFilteredResults(constraint);

                FilterResults results = new FilterResults();
                results.values = filteredResults;

                return results;
            }
        };
    }
share | improve this answer
 
2  
Why you say "override" in 3) ? BaseAdapter doesn't have getFilter(). –  Ixx  May 2 '12 at 11:31
3  
Good catch -- not needed. My custom Adapter class (actually inheriting from AmazingAdapter from the AmazingListView open source widget) implements the android.widget.Filterable interface which requires getFilter(). –  Dustin  May 3 '12 at 14:56
3  
This tutorial helped me. The answer had some unclear things, or maybe I didn't read it with enough concentration. –  Sufian  Mar 26 at 10:53

salam here a example

public Filter getFilter() {
    return new Filter() {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            final FilterResults oReturn = new FilterResults();
            final ArrayList<station> results = new ArrayList<station>();
            if (orig == null)
                orig = items;
            if (constraint != null) {
                if (orig != null && orig.size() > 0) {
                    for (final station g : orig) {
                        if (g.getName().toLowerCase()
                                .contains(constraint.toString()))
                            results.add(g);
                    }
                }
                oReturn.values = results;
            }
            return oReturn;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {
            items = (ArrayList<station>) results.values;
            notifyDataSetChanged();
        }
    };
}

public void notifyDataSetChanged() {
    super.notifyDataSetChanged();
    notifyChanged = true;
}

Add search function to Custom Listview

Android Code Samples  [March 10, 2013 at 8:48 AM]   2,023 views

1. Introduce

Adding search functionality to listview will filters the list data with a matching string, hence provides user an easy way to find the information he needs. In this simple tutorial i am discussing how to enable search filter to android custom ListView.
In this tutorial,we will display list of picture and search picture by its name.

2. Filter Method in Adapter

To filter the list data with a matching string from user,we use a Filter method in Adapter.

Hide content

      /**
  * Filter
  * @author 9Android.net
  *
  */
public void filter(String charText) {
     charText = charText.toLowerCase();
     picList.clear();
     if (charText.length() == 0 ) {
         picList.addAll(listpicOrigin);
     } else {
         for (Picture pic : listpicOrigin) {
             if (pic.getPicName().toLowerCase().contains(charText)) {
                 picList.add(pic);
             }
         }
     }
     notifyDataSetChanged();
}

   
 

3. Create XML layout

activity_main.xml

Hide content  

< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
     xmlns:tools = "http://schemas.android.com/tools"
     android:id = "@+id/LinearLayout1"
     android:layout_width = "match_parent"
     android:layout_height = "match_parent"
     android:orientation = "vertical" >
 
     < ViewFlipper
         android:id = "@+id/viewFlipper1"
         android:layout_width = "match_parent"
         android:layout_height = "fill_parent" >
 
         < include
             android:id = "@+id/listpic_layout"
             layout = "@layout/listpic_layout" />
 
         < include
             android:id = "@+id/viewpic_layout"
             layout = "@layout/view_pic_layout" />
     </ ViewFlipper >
 
</ LinearLayout >

   
 

listpic_layout.xml

Hide content  

< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
     xmlns:tools = "http://schemas.android.com/tools"
     android:id = "@+id/LinearLayout1"
     android:layout_width = "match_parent"
     android:layout_height = "match_parent"
     android:orientation = "vertical" >
 
     < EditText
         android:id = "@+id/search_edt"
         android:layout_width = "match_parent"
         android:layout_height = "wrap_content"
         android:drawableRight = "@drawable/search"
         android:ems = "10"
         android:hint = "Search pic name" >
 
         < requestFocus />
     </ EditText >
 
     < ListView
         android:id = "@+id/listView1"
         android:layout_width = "match_parent"
         android:layout_height = "wrap_content"
         android:dividerHeight = "3dp" >
     </ ListView >
 
</ LinearLayout >

   
 

list_item.xml
Hide content  

<? xml version = "1.0" encoding = "utf-8" ?>
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
     android:id = "@+id/LinearLayout1"
     android:layout_width = "match_parent"
     android:layout_height = "wrap_content"
     android:orientation = "horizontal" >
 
     < ImageView
         android:id = "@+id/pic_icon_img"
         android:layout_width = "120dp"
         android:layout_height = "120dp"
         android:scaleType = "fitXY"
         android:src = "@drawable/ic_launcher" />
 
     < LinearLayout
         android:layout_width = "wrap_content"
         android:layout_height = "match_parent"
         android:layout_weight = "1"
         android:orientation = "vertical" >
 
         < TextView
             android:id = "@+id/pic_name_txt"
             android:layout_width = "fill_parent"
             android:layout_height = "wrap_content"
             android:layout_gravity = "center"
             android:layout_marginTop = "10dp"
             android:layout_weight = "1"
             android:gravity = "center_vertical"
             android:text = "Pic Name"
             android:textAppearance = "?android:attr/textAppearanceLarge"
             android:textStyle = "bold" />
 
         < TextView
             android:id = "@+id/pic_type_txt"
             android:layout_width = "fill_parent"
             android:layout_height = "wrap_content"
             android:layout_weight = "1"
             android:text = "Pic Type"
             android:textAppearance = "?android:attr/textAppearanceMedium" />
     </ LinearLayout >
 
     < ImageView
         android:id = "@+id/imageView2"
         android:layout_width = "wrap_content"
         android:layout_height = "wrap_content"
         android:layout_gravity = "center_vertical"
         android:src = "@drawable/arrow" />
 
</ LinearLayout >

   
 

view_pic_layout.xml
Hide content  

<? xml version = "1.0" encoding = "utf-8" ?>
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
     android:layout_width = "match_parent"
     android:layout_height = "match_parent"
     android:orientation = "vertical" >
 
     < ImageView
         android:id = "@+id/viewpic_img"
         android:layout_width = "fill_parent"
         android:layout_height = "fill_parent"
         android:scaleType = "fitCenter"
         android:src = "@drawable/bikinigirl_3" />
 
</ LinearLayout >

   
 

4. Code application

PicListAdapter.java

Hide content  

public class PicListAdapter extends BaseAdapter {
     private Context mContext;
     private LayoutInflater mInflater;
     private List<Picture> picList = null ;
     private ArrayList<Picture> listpicOrigin;
 
     public PicListAdapter(Context context, List<Picture> picList) {
         mContext = context;
         this .picList = picList;
         mInflater = LayoutInflater.from(mContext);
         this .listpicOrigin = new ArrayList<Picture>();
         this .listpicOrigin.addAll(picList);
     }
 
     public class ViewHolder {
         TextView picName;
         TextView picType;
         ImageView picIcon;
     }
 
     public View getView( int position, View view, ViewGroup parent) {
         final ViewHolder holder;
         if (view == null ) {
             holder = new ViewHolder();
             view = mInflater.inflate(R.layout.list_item, null );
             holder.picName = (TextView) view.findViewById(R.id.pic_name_txt);
             holder.picType = (TextView) view.findViewById(R.id.pic_type_txt);
             holder.picIcon = (ImageView) view.findViewById(R.id.pic_icon_img);
             view.setTag(holder);
         } else {
             holder = (ViewHolder) view.getTag();
         }
 
         holder.picName.setText(picList.get(position).getPicName());
         holder.picType.setText(picList.get(position).getPicType());
         holder.picIcon.setImageResource(picList.get(position).getPicSource());
 
         return view;
     }
 
     public int getCount() {
         return picList.size();
     }
 
     public Picture getItem( int position) {
         return picList.get(position);
     }
 
     public long getItemId( int position) {
         return position;
     }
 
     /**
      * Filter
      * @author 9Android.net
      *
      */
     public void filter(String charText) {
         charText = charText.toLowerCase();
         picList.clear();
         if (charText.length() == 0 ) {
             picList.addAll(listpicOrigin);
         } else {
             for (Picture pic : listpicOrigin) {
                 if (pic.getPicName().toLowerCase().contains(charText)) {
                     picList.add(pic);
                 }
             }
         }
         notifyDataSetChanged();
     }
 
}

   
 

MainActivity.java

Hide content  

public class MainActivity extends Activity implements TextWatcher,
         OnItemClickListener {
 
     private static final int LIST_PIC_SCREEN = 0 ;
     private static final int VIEW_PIC_SCREEN = 1 ;
 
     private String[] listPicName = { "androidgirl_1" , "androidgirl_2" ,
             "androidgirl_3" , "beautifulgirl_1" , "beautifulgirl_2" ,
             "bikinigirl_1" , "bikinigirl_2" , "bikinigirl_3" , "cutegirl_1" ,
             "cutegirl_2" , "cutegirl_3" , "cutegirl_4" , "cutegirl_5" ,
             "hotgirl_1" , "hotgirl_2" , "hotgirl_3" , "nudegirl_1" , "nudegirl_2" ,
             "nudegirl_3" , "nudegirl_4" , "sexygirl_1" , "sexygirl_2" ,
             "sexygirl_3" , "sportgirl_1" , "sportgirl_2" , "sportgirl_3" ,
             "sportgirl_4" };
 
     private String[] listPicType = { "android" , "android" , "android" ,
             "beautiful" , "beautiful" , "bikini" , "bikini" , "bikini" , "cutegirl" ,
             "cutegirl" , "cutegirl" , "cutegirl" , "cutegirl" , "hotgirl" ,
             "hotgirl" , "hotgirl" , "nude" , "nude" , "nude" , "nude" , "sexy" ,
             "sexy" , "sexy" , "sport" , "sport" , "sport" , "sport" };
     private int [] listPicDrawable = { R.drawable.androidgirl_1,
             R.drawable.androidgirl_2, R.drawable.androidgirl_3,
             R.drawable.beautifulgirl_1, R.drawable.beautifulgirl_2,
             R.drawable.bikinigirl_1, R.drawable.bikinigirl_2,
             R.drawable.bikinigirl_3, R.drawable.cutegirl_1,
             R.drawable.cutegirl_2, R.drawable.cutegirl_3,
             R.drawable.cutegirl_4, R.drawable.cutegirl_5, R.drawable.hotgirl_1,
             R.drawable.hotgirl_2, R.drawable.hotgirl_3, R.drawable.nudegirl_1,
             R.drawable.nudegirl_2, R.drawable.nudegirl_3,
             R.drawable.nudegirl_4, R.drawable.sexygirl_1,
             R.drawable.sexygirl_2, R.drawable.sexygirl_3,
             R.drawable.sportgirl_1, R.drawable.sportgirl_2,
             R.drawable.sportgirl_3, R.drawable.sportgirl_4
 
     };
 
     private ArrayList<Picture> listPic = new ArrayList<Picture>();
     private ListView listview;
     private PicListAdapter adapter;
     private EditText searchEdt;
     private ViewFlipper fliper;
     private ImageView viewpic;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         fliper = (ViewFlipper) findViewById(R.id.viewFlipper1);
         listview = (ListView) findViewById(R.id.listView1);
         for ( int i = 0 ; i < listPicName.length; i++) {
             Picture pic = new Picture(listPicName[i], listPicType[i],
                     listPicDrawable[i]);
             listPic.add(pic);
         }
         adapter = new PicListAdapter( this , listPic);
         listview.setAdapter(adapter);
         listview.setOnItemClickListener( this );
 
         searchEdt = (EditText) findViewById(R.id.search_edt);
         searchEdt.addTextChangedListener( this );
         viewpic = (ImageView) findViewById(R.id.viewpic_img);
     }
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         getMenuInflater().inflate(R.menu.activity_main, menu);
         return true ;
     }
 
     /**
      * @author 9Android.net
      */
     public void beforeTextChanged(CharSequence s, int start, int count,
             int after) {
         // TODO Auto-generated method stub
 
     }
 
     public void onTextChanged(CharSequence s, int start, int before, int count) {
         // TODO Auto-generated method stub
 
     }
 
     public void afterTextChanged(Editable s) {
         // TODO Auto-generated method stub
         String text = searchEdt.getText().toString().toLowerCase();
         adapter.filter(text);
     }
 
     /**
      *  @author 9Android.net
      */
     public void onItemClick(AdapterView<?> parent, View view, int position,
             long id) {
         // TODO Auto-generated method stub
         Sliding.slideFromRightToLeft(VIEW_PIC_SCREEN, fliper);
         viewpic.setImageResource(listPic.get(position).getPicSource());
 
     }
 
     /**
      * @author 9Android.net
      * @param : event, keycode of downed button
      * @Objective : Handle keyevent on main activity
      */
     public boolean onKeyDown( int keyCode, KeyEvent event) {
 
         if (keyCode == KeyEvent.KEYCODE_BACK) {
             int screen = fliper.getDisplayedChild();
 
             if (screen == VIEW_PIC_SCREEN) {
                 Sliding.slideFromLeftToRight(LIST_PIC_SCREEN, fliper);
                 return true ;
             }
         }
         return super .onKeyDown(keyCode, event);
     }
 
}

   
 

5. Conclusion

If you want to hide keyboard when load Activity,you put android:windowSoftInputMode=”stateHidden”
into AndroidManifest.xml

Hide content  

< manifest xmlns:android = "http://schemas.android.com/apk/res/android"
     package = "com.example.searchinginlistview"
     android:versionCode = "1"
     android:versionName = "1.0" >
 
     < uses-sdk
         android:minSdkVersion = "8"
         android:targetSdkVersion = "15" />
 
     < application
         android:icon = "@drawable/icon"
         android:label = "@string/app_name"
         android:theme = "@style/AppTheme" >
         < activity
             android:name = ".MainActivity"
             android:label = "@string/title_activity_main"
             android:windowSoftInputMode = "stateHidden"
             >
             < intent-filter >
                 < action android:name = "android.intent.action.MAIN" />
 
                 < category android:name = "android.intent.category.LAUNCHER" />
             </ intent-filter >
         </ activity >
     </ application >
 
</ manifest >

   
 

In this tutorial, we have known about how to enable search functionality to custom Listview. You can improve it to enable search functionality to custom Expandable Listview.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值