现在的位置: 首页 > 综合 > 正文

Filtering ListView with custom (object) adapter

2017年09月30日 ⁄ 综合 ⁄ 共 17193字 ⁄ 字号 评论关闭

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
 

    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.

抱歉!评论已关闭.