J'ai créé une vue de liste avec plusieurs éléments en ligne. J'ai également créé un champ de recherche ci-dessus. Je souhaite implémenter la fonctionnalité de recherche sur la base de champs particuliers de la liste. Comment puis-je atteindre cet objectif? Toute aide serait appréciée.
Vous devez utiliser pour cela le modèle, la vue de liste et l'adaptateur personnalisé avec filtrage. J'ai créé une démo pour cela.
Supposons que vous ayez un modèle nommé Product et que vous affichez son contenu dans une vue de liste personnalisée où le nom et le prix sont affichés dans une vue de texte. Je veux dire dans une ligne personnalisée ayant deux vues de texte, et vous souhaitez filtrer la liste par l'un des champs de ligne personnalisée. Ici, j'ai filtré avec "nom"
Captures d'écran:
Initiale
Filtré
Code source
public class Product {
public String name;
public Integer price;
public Product(String name, Integer price) {
super();
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
}
public class MainActivity extends Activity {
private LinearLayout llContainer;
private EditText etSearch;
private ListView lvProducts;
private ArrayList<Product> mProductArrayList = new ArrayList<Product>();
private MyAdapter adapter1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialize();
// Add Text Change Listener to EditText
etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Call back the Adapter with current character to Filter
adapter1.getFilter().filter(s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
private void initialize() {
etSearch = (EditText) findViewById(R.id.etSearch);
lvProducts = (ListView)findViewById(R.id.lvOS);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
mProductArrayList.add(new Product("a", 100));
mProductArrayList.add(new Product("b", 200));
mProductArrayList.add(new Product("c", 300));
mProductArrayList.add(new Product("d", 400));
mProductArrayList.add(new Product("e", 500));
mProductArrayList.add(new Product("f", 600));
mProductArrayList.add(new Product("g", 700));
mProductArrayList.add(new Product("h", 800));
mProductArrayList.add(new Product("i", 900));
mProductArrayList.add(new Product("j", 1000));
mProductArrayList.add(new Product("k", 1100));
mProductArrayList.add(new Product("l", 1200));
mProductArrayList.add(new Product("m", 1000));
mProductArrayList.add(new Product("n", 1300));
mProductArrayList.add(new Product("o", 1400));
mProductArrayList.add(new Product("p", 1500));
adapter1 = new MyAdapter(MainActivity.this, mProductArrayList);
lvProducts.setAdapter(adapter1);
}
// Adapter Class
public class MyAdapter extends BaseAdapter implements Filterable {
private ArrayList<Product> mOriginalValues; // Original Values
private ArrayList<Product> mDisplayedValues; // Values to be displayed
LayoutInflater inflater;
public MyAdapter(Context context, ArrayList<Product> mProductArrayList) {
this.mOriginalValues = mProductArrayList;
this.mDisplayedValues = mProductArrayList;
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mDisplayedValues.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
LinearLayout llContainer;
TextView tvName,tvPrice;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.row, null);
holder.llContainer = (LinearLayout)convertView.findViewById(R.id.llContainer);
holder.tvName = (TextView) convertView.findViewById(R.id.tvName);
holder.tvPrice = (TextView) convertView.findViewById(R.id.tvPrice);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvName.setText(mDisplayedValues.get(position).name);
holder.tvPrice.setText(mDisplayedValues.get(position).price+"");
holder.llContainer.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(MainActivity.this, mDisplayedValues.get(position).name, Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,FilterResults results) {
mDisplayedValues = (ArrayList<Product>) 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
ArrayList<Product> FilteredArrList = new ArrayList<Product>();
if (mOriginalValues == null) {
mOriginalValues = new ArrayList<Product>(mDisplayedValues); // 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).name;
if (data.toLowerCase().startsWith(constraint.toString())) {
FilteredArrList.add(new Product(mOriginalValues.get(i).name,mOriginalValues.get(i).price));
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
return filter;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical" >
<EditText
Android:id="@+id/etSearch"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
/>
<ListView
Android:id="@+id/lvProducts"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
></ListView>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/llContainer"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="horizontal" >
<TextView
Android:id="@+id/tvName"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:singleLine="true"
Android:layout_weight="1"
/>
<TextView
Android:id="@+id/tvPrice"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:singleLine="true"
Android:layout_weight="1"
/>
</LinearLayout>
Vous pouvez définir un TextWatcher pour votre zone de recherche et changer votre curseur sur onTextChanged () sur TextWatcher comme les codes ci-dessous:
TextWatcher filterNameTextWatcher = new TextWatcher()
public void beforeTextChanged(CharSequence s, int start, int count,int after)
{
}
public void onTextChanged(CharSequence s,int start, int before,int count)
{
Cursor FilteredNameList = ZoneCardDBAdapter.instance.CursorFilteredName(s.toString());
Listadapter.changeCursor(FilteredNameList);
}
@Override
public void afterTextChanged(Editable arg0)
{
}
};
EditText filterTextName = (EditText)this.findViewById(R.id.edtZoneCardNameFilter);
filterTextCPName.addTextChangedListener(filterNameTextWatcher);
pour cela, vous devez d'abord ajouter un edittext, où vous tapez pour filtrer les données de la liste,
puis activez la filtration dans la liste,
editText = (EditText) findViewById(R.id.searchList);
adapter = new CustomListViewAdapter(this,
R.layout.list_row, rowItems);
listView.setAdapter(adapter);
listView.setTextFilterEnabled(true);
Ensuite, vous devez ajouter TextChangeListener()
pour l'edittext,
editText.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
}
public void afterTextChanged(Editable arg0) {
MyActivityName.this.adapter.getFilter().filter(arg0);
}
});
Utilisez le type de méthode ci-dessous.
your edit text box.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable theWatchedText) {
}
});
}