
I have an EditText and Custom ListView Adapter connected sqllite db.
I can add, remove and edit records. The next goal is filter the records by EditText.
I wroted this codes but It didn’t filtered correctly.
private EditText et_search_filter;
private TextWatcher watcher_search_filter;
et_search_filter = (EditText) findViewById(id.et_search_box);
et_search_filter.addTextChangedListener(watcher_search_filter);
watcher_search_filter = new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void afterTextChanged(Editable s) {
}
};
Here my cursor method:
public ArrayList<Item> item_get_all() {
ArrayList<Item> itemList = new ArrayList<Item>();
String selectQuery = "SELECT * FROM " + TABLE_ITEMS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
Item dbitems = new Item();
dbitems.setID(Integer.parseInt(cursor.getString(cursor.getColumnIndex(items_id))));
dbitems.setName(cursor.getString(cursor.getColumnIndex(items_item_name)));
dbitems.setBrand(cursor.getString(cursor.getColumnIndex(items_brand)));
dbitems.setItemType(cursor.getString(cursor.getColumnIndex(items_type)));
dbitems.setModel(cursor.getString(cursor.getColumnIndex(items_model)));
dbitems.setNote(cursor.getString(cursor.getColumnIndex(items_note)));
dbitems.setPurchaseFrom(cursor.getString(cursor.getColumnIndex(items_purchase_from)));
dbitems.setPurchasePrice(cursor.getString(cursor.getColumnIndex(items_price)));
dbitems.setPurchaseDate(cursor.getLong(cursor.getColumnIndex(items_purchase_date)));
itemList.add(dbitems);
} while (cursor.moveToNext());
}
db.close();
return itemList;
}
And I called cursor adapter like this:
public void getItemList() {
ArrayList<Item> itemArray = new ArrayList<Item>();
itemArray = db.item_get_all();
adapter = new ItemAdapter(this, R.layout.items_row, itemArray);
ilistViewItems.setAdapter(adapter);
}
Here are my ItemAdapter.java and Item_row.xml files:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="@+id/tv_item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="@string/nullstr"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#ffffff"
android:textSize="13dp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_item_brand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/tv_item_name"
android:text="@string/nullstr"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#bbbbbb"
android:textSize="11dp" />
<TextView
android:id="@+id/tv_purchase_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/tv_item_name"
android:text="@string/nullstr"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#aabbbb"
android:textSize="11dp" />
</RelativeLayout>
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import db.Item;
public class ItemAdapter extends ArrayAdapter<Item>{
private ArrayList<Item> items;
private TextView item_name;
private TextView item_brand;
private TextView item_purchase_date;
public ItemAdapter(Context context, int textViewResourceId, ArrayList<Item> objects) {
super(context, textViewResourceId, objects);
this.items = objects;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.items_row, null);
}
item_name = (TextView) convertView.findViewById(R.id.tv_item_name);
item_brand = (TextView) convertView.findViewById(R.id.tv_item_brand);
item_purchase_date = (TextView) convertView.findViewById(R.id.tv_purchase_date);
item_name.setText(items.get(position).getName());
item_brand.setText("[" + items.get(position).getItemType() + "] " + items.get(position).getBrand() + " " + items.get(position).getModel());
item_purchase_date.setText(items.get(position).getPurchasedDateStr());
return convertView;
}
}
Rewrite
Have you implemented Item’s toString() method?
When I use this method with every thing you have posted, the EditText filters the ListView just fine. Let me know if this simple change works for you.
Efficiency
I want to point out a few tricks for your existing code to run faster.
Look at your database adapter’s get_item_all() method.
longdata types. You should change the id in Item from anintto alongand use Cursor.getLong().All together, this is more efficient:
Next, look at Item.getView().
item.get(position)multiple times every time getView() is called. Whenever the user scrolls the ListView the adapter uses getView() to display each row, you only need to call findViewById() whenconvertViewis null.All together:
Create a variable called
LayoutInflater mInflaterand initialize it in your constructor:In your ItemAdapter add this nested class:
In getView():
Do you see how much less work happens if convertView has already been created? Hope that helps.