如何在我的搜索字符串中搜索任何字符?
How do I search any character in my search strings?
我目前正在使用字符序列来搜索我的字符串。如何搜索字符串中的任何字符?例如:我有名字“Justin”和“Jacks”,如果我输入“k”,则只有 jack 出现,当我输入“s”时,justin 和 jacks 都会出现,因为它们都有字母 s,如果我只输入 us justin出现等等。我该怎么做?
到目前为止,这是我的代码:
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
MainActivity.this.adapter.getFilter().filter(cs);
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
这是我用于测试项目的整个示例代码:
http://www.androidhive.info/2012/09/android-adding-search-functionality-to-listview/
让我们为您的案例编写一些示例代码。
String[] names = {"Justin","Jacks"};
String searchKeyword = "k";
for ( int i = 0; i < names.length; i ++ ){
if (names[i].contains(searchKeyword) == true)
System.out.print(names[i]); // print out match results
// system will print "Jacks" only
}
在您的适配器中尝试以下代码以获取列表中的过滤器数据:
private Filter mFilter;
private List<String> mCompleteList,mList;
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
results.values = mCompleteList;
results.count = mCompleteList.size();
} else {
List<String> beanList = new ArrayList<String>();
for (String bean : mCompleteList) {
if (bean.toUpperCase().contains(constraint.toString().toUpperCase())) {
beanList.add(bean);
}
}
results.values = beanList;
results.count = beanList.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mList = (List<String>) results.values;
notifyDataSetChanged();
}
};
}
return mFilter;
}
而且不需要 MainActivity.this.adapter.getFilter().filter(cs);在文本更改中,您可以使用 adapter.getFilter().filter(cs);因为 adapter 是 class.
的私有变量
之后
lv = (ListView) findViewById(R.id.list_view);
只需添加下面提到的这一行,
lv.setTextFilterEnabled(true);
因此,您将得到类似于 this 示例的结果。
试试这个,
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true">
<EditText
android:id="@+id/editTxt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:maxLines="1" />
<ListView android:id="@+id/listView"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1"/>
<Button android:id="@+id/addBtn"
android:text="Add planet"
android:onClick="addPlanet"
android:layout_weight="0.5"
android:layout_height="80dp"
android:layout_width="match_parent"/>
</LinearLayout>
这是你的dialog.xml
<?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" >
<EditText
android:id="@+id/editTextPlanet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:ems="10"
android:hint="Insert your planet name" >
<requestFocus />
</EditText>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Add" />
</LinearLayout>
这是你的img_row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="left"
android:paddingLeft="0dip"
android:src="@drawable/planet" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/img"
android:layout_toRightOf="@+id/img"
android:textStyle="bold" />
<TextView
android:id="@+id/dist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/name"
android:layout_gravity="center"
android:layout_marginTop="2dip"
android:layout_toRightOf="@id/img"
android:gravity="right"
android:textSize="8dp"
android:textStyle="italic" />
</RelativeLayout>
这是你的row_layout.xml
<?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" >
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:textStyle="bold"
/>
<TextView
android:id="@+id/dist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="8dp"
android:textStyle="italic"/>
</LinearLayout>
这是你的Planet.java
/*
* Copyright (C) 2012 jfrankie (http://www.survivingwithandroid.com)
*
* 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 com.survivingwithandroid.listview.SimpleList;
public class Planet {
private String name;
private Integer distance;
private String descr;
private int idImg;
public Planet(String name, Integer distance) {
this.name = name;
this.distance = distance;
}
public Planet(String name, String descr) {
this.name = name;
this.descr = descr;
}
public Planet(String name, Integer distance, String descr, int idImg) {
this.name = name;
this.distance = distance;
this.descr = descr;
this.idImg = idImg;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getDistance() {
return distance;
}
public void setDistance(Integer distance) {
this.distance = distance;
}
public int getIdImg() {
return idImg;
}
public void setIdImg(int idImg) {
this.idImg = idImg;
}
}
这是你的PlanetAdapter.java
/*
* Copyright (C) 2012 jfrankie (http://www.survivingwithandroid.com)
*
* 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 com.survivingwithandroid.listview.SimpleList;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
public class PlanetAdapter extends ArrayAdapter<Planet> implements Filterable {
private List<Planet> planetList;
private Context context;
private Filter planetFilter;
private List<Planet> origPlanetList;
public PlanetAdapter(List<Planet> planetList, Context ctx) {
super(ctx, R.layout.img_row_layout, planetList);
this.planetList = planetList;
this.context = ctx;
this.origPlanetList = planetList;
}
public int getCount() {
return planetList.size();
}
public Planet getItem(int position) {
return planetList.get(position);
}
public long getItemId(int position) {
return planetList.get(position).hashCode();
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
PlanetHolder holder = new PlanetHolder();
// First let's verify the convertView is not null
if (convertView == null) {
// This a new view we inflate the new layout
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.img_row_layout, null);
// Now we can fill the layout with the right values
TextView tv = (TextView) v.findViewById(R.id.name);
TextView distView = (TextView) v.findViewById(R.id.dist);
holder.planetNameView = tv;
holder.distView = distView;
v.setTag(holder);
}
else
holder = (PlanetHolder) v.getTag();
Planet p = planetList.get(position);
holder.planetNameView.setText(p.getName());
holder.distView.setText("" + p.getDistance());
return v;
}
public void resetData() {
planetList = origPlanetList;
}
/* *********************************
* We use the holder pattern
* It makes the view faster and avoid finding the component
* **********************************/
private static class PlanetHolder {
public TextView planetNameView;
public TextView distView;
}
/*
* We create our filter
*/
@Override
public Filter getFilter() {
if (planetFilter == null)
planetFilter = new PlanetFilter();
return planetFilter;
}
private class PlanetFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// We implement here the filter logic
if (constraint == null || constraint.length() == 0) {
// No filter implemented we return all the list
results.values = origPlanetList;
results.count = origPlanetList.size();
}
else {
// We perform filtering operation
List<Planet> nPlanetList = new ArrayList<Planet>();
for (Planet p : planetList) {
if (p.getName().toUpperCase().startsWith(constraint.toString().toUpperCase()))
nPlanetList.add(p);
}
results.values = nPlanetList;
results.count = nPlanetList.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
// Now we have to inform the adapter about the new list filtered
if (results.count == 0)
notifyDataSetInvalidated();
else {
planetList = (List<Planet>) results.values;
notifyDataSetChanged();
}
}
}
}
这是你的 MainActivity.java
/*
* Copyright (C) 2012 jfrankie (http://www.survivingwithandroid.com)
*
* 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 com.survivingwithandroid.listview.SimpleList;
/**
* @author Surviving with android (jfrankie)
*
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
// The data to show
List<Planet> planetsList = new ArrayList<Planet>();
PlanetAdapter aAdpt;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initList();
// We get the ListView component from the layout
ListView lv = (ListView) findViewById(R.id.listView);
// This is a simple adapter that accepts as parameter
// Context
// Data list
// The row layout that is used during the row creation
// The keys used to retrieve the data
// The View id used to show the data. The key number and the view id must match
//aAdpt = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, planetsList);
aAdpt = new PlanetAdapter(planetsList, this);
lv.setAdapter(aAdpt);
// React to user clicks on item
// lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
//
// public void onItemClick(AdapterView<?> parentAdapter, View view, int position,
// long id) {
//
//
// // We know the View is a <extView so we can cast it
// TextView clickedView = (TextView) view;
//
// Toast.makeText(MainActivity.this, "Item with id ["+id+"] - Position ["+position+"] - Planet ["+clickedView.getText()+"]", Toast.LENGTH_SHORT).show();
//
// }
// });
// we register for the contextmneu
registerForContextMenu(lv);
// TextFilter
lv.setTextFilterEnabled(true);
EditText editTxt = (EditText) findViewById(R.id.editTxt);
editTxt.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
System.out.println("Text ["+s+"] - Start ["+start+"] - Before ["+before+"] - Count ["+count+"]");
if (count < before) {
// We're deleting char so we need to reset the adapter data
aAdpt.resetData();
}
aAdpt.getFilter().filter(s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
// We want to create a context Menu when the user long click on an item
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) menuInfo;
// We know that each row in the adapter is a Map
Planet planet = aAdpt.getItem(aInfo.position);
menu.setHeaderTitle("Options for " + planet.getName());
menu.add(1, 1, 1, "Details");
menu.add(1, 2, 2, "Delete");
}
// This method is called when user selects an Item in the Context menu
@Override
public boolean onContextItemSelected(MenuItem item) {
int itemId = item.getItemId();
AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) item.getMenuInfo();
planetsList.remove(aInfo.position);
aAdpt.notifyDataSetChanged();
return true;
}
private void initList() {
// We populate the planets
planetsList.add(new Planet("Mercury", 10));
planetsList.add(new Planet("Venus", 20));
planetsList.add(new Planet("Mars", 30));
planetsList.add(new Planet("Jupiter", 40));
planetsList.add(new Planet("Saturn", 50));
planetsList.add(new Planet("Uranus", 60));
planetsList.add(new Planet("Neptune", 70));
}
// Handle user click
public void addPlanet(View view) {
final Dialog d = new Dialog(this);
d.setContentView(R.layout.dialog);
d.setTitle("Add planet");
d.setCancelable(true);
final EditText edit = (EditText) d.findViewById(R.id.editTextPlanet);
Button b = (Button) d.findViewById(R.id.button1);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String planetName = edit.getText().toString();
MainActivity.this.planetsList.add(new Planet(planetName, 0));
MainActivity.this.aAdpt.notifyDataSetChanged(); // We notify the data model is changed
d.dismiss();
}
});
d.show();
}
}
就是这样。
请找到工作示例,
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
MainActivity.this.adapter.filter(cs);
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
在您的适配器中创建您自己的过滤方法,
public class FieldsAdapter extends BaseAdapter{
Context mContext;
LayoutInflater inflater;
private List<String> mainDataList = null;
private ArrayList<String> arrayList;
public FieldsAdapter(Context context,List<String> fieldList) {
mContext = context;
mainDataList = fieldList;
inflater = LayoutInflater.from(context);
this.arrayList = new ArrayList<String>();
this.arrayList.addAll(mainDataList);
}
@Override
public int getCount() {
return mainDataList.size();
}
@Override
public Object getItem(int position) {
return mainDataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.edit_field_item, null);
holder.txtFieldName = (TextView) convertView.findViewById(R.id.txt_field_name);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.txtFieldName.setText(mainDataList.get(position));
return convertView;
}
static class ViewHolder{
protected TextView txtFieldName;
}
public void filter(String queryText){
queryText = queryText.toLowerCase();
mainDataList.clear();
if(queryText.length()==0){
mainDataList.addAll(arrayList);
}else{
for(FieldsPOJO field:arrayList){
if(field.getFieldName().toString().toLowerCase().contains(queryText)){
mainDataList.add(field);
}
}
}
notifyDataSetChanged();
}
}
如有任何疑问,请随时在评论部分post提出您的疑问。编码愉快..
private class ModelFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
FilterResults result = new FilterResults();
if (constraint != null && constraint.toString().length() > 0) {
ArrayList<UserCommunicationStatus> filteredItems = new ArrayList<UserCommunicationStatus>();
for (int i = 0, l = AllcommuserList.size(); i < l; i++) {
UserCommunicationStatus m = AllcommuserList.get(i);
String name = m.getFirstName().toLowerCase() + " " + m.getLastName().toLowerCase();
if (name.contains(constraint))
filteredItems.add(m);
}
result.count = filteredItems.size();
result.values = filteredItems;
} else {
synchronized (this) {
result.values = AllcommuserList;
result.count = AllcommuserList.size();
}
}
return result;
}
这是我的实现,得到的结果和你问的一样,希望对你有帮助。
谢谢
实际上,android 中的默认 Arrayadapter class 似乎只能从整个单词的开头搜索,但是通过使用自定义 Arrayadapter class,您可以搜索部分内容任意字符串。
我已经创建了整个自定义 class 并发布了库。
这是非常容易使用。
您可以从 here 或单击下面提供的 link 查看实施和使用情况。
https://github.com/mohitjha727/Advanced-Search-Filter
你可以参考这个简单的例子——
我们有名字“Mohit”和“Rohan”,如果我们只输入“M”,Mohit 就会出现在搜索结果中,但是当我们输入“oh”时,Mohit 和 Rohan 都会出现,因为它们具有共同点字母 'oh'.
谢谢。
我目前正在使用字符序列来搜索我的字符串。如何搜索字符串中的任何字符?例如:我有名字“Justin”和“Jacks”,如果我输入“k”,则只有 jack 出现,当我输入“s”时,justin 和 jacks 都会出现,因为它们都有字母 s,如果我只输入 us justin出现等等。我该怎么做? 到目前为止,这是我的代码:
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
MainActivity.this.adapter.getFilter().filter(cs);
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
这是我用于测试项目的整个示例代码: http://www.androidhive.info/2012/09/android-adding-search-functionality-to-listview/
让我们为您的案例编写一些示例代码。
String[] names = {"Justin","Jacks"};
String searchKeyword = "k";
for ( int i = 0; i < names.length; i ++ ){
if (names[i].contains(searchKeyword) == true)
System.out.print(names[i]); // print out match results
// system will print "Jacks" only
}
在您的适配器中尝试以下代码以获取列表中的过滤器数据:
private Filter mFilter;
private List<String> mCompleteList,mList;
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
results.values = mCompleteList;
results.count = mCompleteList.size();
} else {
List<String> beanList = new ArrayList<String>();
for (String bean : mCompleteList) {
if (bean.toUpperCase().contains(constraint.toString().toUpperCase())) {
beanList.add(bean);
}
}
results.values = beanList;
results.count = beanList.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mList = (List<String>) results.values;
notifyDataSetChanged();
}
};
}
return mFilter;
}
而且不需要 MainActivity.this.adapter.getFilter().filter(cs);在文本更改中,您可以使用 adapter.getFilter().filter(cs);因为 adapter 是 class.
的私有变量lv = (ListView) findViewById(R.id.list_view);
只需添加下面提到的这一行,
lv.setTextFilterEnabled(true);
因此,您将得到类似于 this 示例的结果。
试试这个,
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true">
<EditText
android:id="@+id/editTxt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:maxLines="1" />
<ListView android:id="@+id/listView"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1"/>
<Button android:id="@+id/addBtn"
android:text="Add planet"
android:onClick="addPlanet"
android:layout_weight="0.5"
android:layout_height="80dp"
android:layout_width="match_parent"/>
</LinearLayout>
这是你的dialog.xml
<?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" >
<EditText
android:id="@+id/editTextPlanet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:ems="10"
android:hint="Insert your planet name" >
<requestFocus />
</EditText>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Add" />
</LinearLayout>
这是你的img_row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="left"
android:paddingLeft="0dip"
android:src="@drawable/planet" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/img"
android:layout_toRightOf="@+id/img"
android:textStyle="bold" />
<TextView
android:id="@+id/dist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/name"
android:layout_gravity="center"
android:layout_marginTop="2dip"
android:layout_toRightOf="@id/img"
android:gravity="right"
android:textSize="8dp"
android:textStyle="italic" />
</RelativeLayout>
这是你的row_layout.xml
<?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" >
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:textStyle="bold"
/>
<TextView
android:id="@+id/dist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="8dp"
android:textStyle="italic"/>
</LinearLayout>
这是你的Planet.java
/*
* Copyright (C) 2012 jfrankie (http://www.survivingwithandroid.com)
*
* 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 com.survivingwithandroid.listview.SimpleList;
public class Planet {
private String name;
private Integer distance;
private String descr;
private int idImg;
public Planet(String name, Integer distance) {
this.name = name;
this.distance = distance;
}
public Planet(String name, String descr) {
this.name = name;
this.descr = descr;
}
public Planet(String name, Integer distance, String descr, int idImg) {
this.name = name;
this.distance = distance;
this.descr = descr;
this.idImg = idImg;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getDistance() {
return distance;
}
public void setDistance(Integer distance) {
this.distance = distance;
}
public int getIdImg() {
return idImg;
}
public void setIdImg(int idImg) {
this.idImg = idImg;
}
}
这是你的PlanetAdapter.java
/*
* Copyright (C) 2012 jfrankie (http://www.survivingwithandroid.com)
*
* 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 com.survivingwithandroid.listview.SimpleList;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
public class PlanetAdapter extends ArrayAdapter<Planet> implements Filterable {
private List<Planet> planetList;
private Context context;
private Filter planetFilter;
private List<Planet> origPlanetList;
public PlanetAdapter(List<Planet> planetList, Context ctx) {
super(ctx, R.layout.img_row_layout, planetList);
this.planetList = planetList;
this.context = ctx;
this.origPlanetList = planetList;
}
public int getCount() {
return planetList.size();
}
public Planet getItem(int position) {
return planetList.get(position);
}
public long getItemId(int position) {
return planetList.get(position).hashCode();
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
PlanetHolder holder = new PlanetHolder();
// First let's verify the convertView is not null
if (convertView == null) {
// This a new view we inflate the new layout
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.img_row_layout, null);
// Now we can fill the layout with the right values
TextView tv = (TextView) v.findViewById(R.id.name);
TextView distView = (TextView) v.findViewById(R.id.dist);
holder.planetNameView = tv;
holder.distView = distView;
v.setTag(holder);
}
else
holder = (PlanetHolder) v.getTag();
Planet p = planetList.get(position);
holder.planetNameView.setText(p.getName());
holder.distView.setText("" + p.getDistance());
return v;
}
public void resetData() {
planetList = origPlanetList;
}
/* *********************************
* We use the holder pattern
* It makes the view faster and avoid finding the component
* **********************************/
private static class PlanetHolder {
public TextView planetNameView;
public TextView distView;
}
/*
* We create our filter
*/
@Override
public Filter getFilter() {
if (planetFilter == null)
planetFilter = new PlanetFilter();
return planetFilter;
}
private class PlanetFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// We implement here the filter logic
if (constraint == null || constraint.length() == 0) {
// No filter implemented we return all the list
results.values = origPlanetList;
results.count = origPlanetList.size();
}
else {
// We perform filtering operation
List<Planet> nPlanetList = new ArrayList<Planet>();
for (Planet p : planetList) {
if (p.getName().toUpperCase().startsWith(constraint.toString().toUpperCase()))
nPlanetList.add(p);
}
results.values = nPlanetList;
results.count = nPlanetList.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
// Now we have to inform the adapter about the new list filtered
if (results.count == 0)
notifyDataSetInvalidated();
else {
planetList = (List<Planet>) results.values;
notifyDataSetChanged();
}
}
}
}
这是你的 MainActivity.java
/*
* Copyright (C) 2012 jfrankie (http://www.survivingwithandroid.com)
*
* 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 com.survivingwithandroid.listview.SimpleList;
/**
* @author Surviving with android (jfrankie)
*
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
// The data to show
List<Planet> planetsList = new ArrayList<Planet>();
PlanetAdapter aAdpt;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initList();
// We get the ListView component from the layout
ListView lv = (ListView) findViewById(R.id.listView);
// This is a simple adapter that accepts as parameter
// Context
// Data list
// The row layout that is used during the row creation
// The keys used to retrieve the data
// The View id used to show the data. The key number and the view id must match
//aAdpt = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, planetsList);
aAdpt = new PlanetAdapter(planetsList, this);
lv.setAdapter(aAdpt);
// React to user clicks on item
// lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
//
// public void onItemClick(AdapterView<?> parentAdapter, View view, int position,
// long id) {
//
//
// // We know the View is a <extView so we can cast it
// TextView clickedView = (TextView) view;
//
// Toast.makeText(MainActivity.this, "Item with id ["+id+"] - Position ["+position+"] - Planet ["+clickedView.getText()+"]", Toast.LENGTH_SHORT).show();
//
// }
// });
// we register for the contextmneu
registerForContextMenu(lv);
// TextFilter
lv.setTextFilterEnabled(true);
EditText editTxt = (EditText) findViewById(R.id.editTxt);
editTxt.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
System.out.println("Text ["+s+"] - Start ["+start+"] - Before ["+before+"] - Count ["+count+"]");
if (count < before) {
// We're deleting char so we need to reset the adapter data
aAdpt.resetData();
}
aAdpt.getFilter().filter(s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
// We want to create a context Menu when the user long click on an item
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) menuInfo;
// We know that each row in the adapter is a Map
Planet planet = aAdpt.getItem(aInfo.position);
menu.setHeaderTitle("Options for " + planet.getName());
menu.add(1, 1, 1, "Details");
menu.add(1, 2, 2, "Delete");
}
// This method is called when user selects an Item in the Context menu
@Override
public boolean onContextItemSelected(MenuItem item) {
int itemId = item.getItemId();
AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) item.getMenuInfo();
planetsList.remove(aInfo.position);
aAdpt.notifyDataSetChanged();
return true;
}
private void initList() {
// We populate the planets
planetsList.add(new Planet("Mercury", 10));
planetsList.add(new Planet("Venus", 20));
planetsList.add(new Planet("Mars", 30));
planetsList.add(new Planet("Jupiter", 40));
planetsList.add(new Planet("Saturn", 50));
planetsList.add(new Planet("Uranus", 60));
planetsList.add(new Planet("Neptune", 70));
}
// Handle user click
public void addPlanet(View view) {
final Dialog d = new Dialog(this);
d.setContentView(R.layout.dialog);
d.setTitle("Add planet");
d.setCancelable(true);
final EditText edit = (EditText) d.findViewById(R.id.editTextPlanet);
Button b = (Button) d.findViewById(R.id.button1);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String planetName = edit.getText().toString();
MainActivity.this.planetsList.add(new Planet(planetName, 0));
MainActivity.this.aAdpt.notifyDataSetChanged(); // We notify the data model is changed
d.dismiss();
}
});
d.show();
}
}
就是这样。
请找到工作示例,
inputSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
MainActivity.this.adapter.filter(cs);
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
在您的适配器中创建您自己的过滤方法,
public class FieldsAdapter extends BaseAdapter{
Context mContext;
LayoutInflater inflater;
private List<String> mainDataList = null;
private ArrayList<String> arrayList;
public FieldsAdapter(Context context,List<String> fieldList) {
mContext = context;
mainDataList = fieldList;
inflater = LayoutInflater.from(context);
this.arrayList = new ArrayList<String>();
this.arrayList.addAll(mainDataList);
}
@Override
public int getCount() {
return mainDataList.size();
}
@Override
public Object getItem(int position) {
return mainDataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.edit_field_item, null);
holder.txtFieldName = (TextView) convertView.findViewById(R.id.txt_field_name);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.txtFieldName.setText(mainDataList.get(position));
return convertView;
}
static class ViewHolder{
protected TextView txtFieldName;
}
public void filter(String queryText){
queryText = queryText.toLowerCase();
mainDataList.clear();
if(queryText.length()==0){
mainDataList.addAll(arrayList);
}else{
for(FieldsPOJO field:arrayList){
if(field.getFieldName().toString().toLowerCase().contains(queryText)){
mainDataList.add(field);
}
}
}
notifyDataSetChanged();
}
}
如有任何疑问,请随时在评论部分post提出您的疑问。编码愉快..
private class ModelFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
constraint = constraint.toString().toLowerCase();
FilterResults result = new FilterResults();
if (constraint != null && constraint.toString().length() > 0) {
ArrayList<UserCommunicationStatus> filteredItems = new ArrayList<UserCommunicationStatus>();
for (int i = 0, l = AllcommuserList.size(); i < l; i++) {
UserCommunicationStatus m = AllcommuserList.get(i);
String name = m.getFirstName().toLowerCase() + " " + m.getLastName().toLowerCase();
if (name.contains(constraint))
filteredItems.add(m);
}
result.count = filteredItems.size();
result.values = filteredItems;
} else {
synchronized (this) {
result.values = AllcommuserList;
result.count = AllcommuserList.size();
}
}
return result;
}
这是我的实现,得到的结果和你问的一样,希望对你有帮助。
谢谢
实际上,android 中的默认 Arrayadapter class 似乎只能从整个单词的开头搜索,但是通过使用自定义 Arrayadapter class,您可以搜索部分内容任意字符串。 我已经创建了整个自定义 class 并发布了库。 这是非常容易使用。 您可以从 here 或单击下面提供的 link 查看实施和使用情况。
https://github.com/mohitjha727/Advanced-Search-Filter
你可以参考这个简单的例子——
我们有名字“Mohit”和“Rohan”,如果我们只输入“M”,Mohit 就会出现在搜索结果中,但是当我们输入“oh”时,Mohit 和 Rohan 都会出现,因为它们具有共同点字母 'oh'.
谢谢。