Hello I am googling on that issue for long time but no solution i have ListFragment that show data from SQlite i want to build the option to filter by TextChange i Added the widjet and its working perfect - but how to make the filter ?? getFilter().filter() is not enough .
this is fragmentList
public class CarGallery extends ListFragment {
public static final String ROW_ID = "row_id"; // Intent extra key
private int contentFrameId;
private SimpleCursorAdapter myCarSimpleCursorAdapter;
private SearchView searchView;
private SearchManager searchManager;
private Cursor cursor;
private String[] from;
private int[] to;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
contentFrameId= ((ViewGroup) getView().getParent()).getId();
// map each contact's name to a TextView in the ListView layout
from = new String[] {"number","manufacturer","model","img"};
// in file car_row.xml
to = new int[] {R.id.textViewNumber,R.id.textViewManufacturer,R.id.textViewModel,R.id.imageViewCar};
myCarSimpleCursorAdapter = new SimpleCursorAdapter(getActivity().getApplicationContext(),
R.layout.car_row, // layout to inflate it
null , // cursor adapter : if null then it will be created within the constructor
from , to , 0 );
myCarSimpleCursorAdapter.setViewBinder(new MyViewBinder());
setListAdapter(myCarSimpleCursorAdapter); //databinding --> set contactView's adapter
}
@Override
public void onResume() {
super.onResume();
// create new GetCarsTask and execute it
// our inner class
new GetCarTask().execute();// (Object[]) null
getActivity().setTitle(R.string.actionbarTitleGallery);
}
@Override
public void onStop() {
super.onStop();
cursor = myCarSimpleCursorAdapter.getCursor(); // get current Cursor
if (cursor != null)
cursor.deactivate(); // deactivate it
myCarSimpleCursorAdapter.changeCursor(null); // adapted now has no Cursor
}
////// performs database query outside GUI thread/////////////
private class GetCarTask extends AsyncTask<Void , Void , Cursor>{
DatabaseConnector databaseConnector = new DatabaseConnector(getActivity().getApplicationContext());
@Override
protected Cursor doInBackground(Void... voids) {
databaseConnector.open();
return databaseConnector.getAllCars();
}
@Override
protected void onPostExecute(Cursor result) {
myCarSimpleCursorAdapter.changeCursor(result);
databaseConnector.close();
}
}
/////// MyViewBinder Class////////////////////////////////
public class MyViewBinder implements SimpleCursorAdapter.ViewBinder {
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
int viewID = view.getId();
switch (viewID) {
case R.id.textViewNumber:
TextView carNumber = (TextView) view;
String car_number;
car_number = cursor.getString(cursor.getColumnIndex("number"));
carNumber.setText(car_number);
break:
case R.id.textViewManufacturer:
TextView carManufacturer = (TextView) view;
String car_manufacturer;
car_manufacturer = cursor.getString(cursor.getColumnIndex("manufacturer"));
carManufacturer.setText(car_manufacturer);
break;
case R.id.textViewModel:
TextView carModel = (TextView) view;
String car_model;
car_model = cursor.getString(cursor.getColumnIndex("model"));
carModel.setText(car_model);
break;
case R.id.imageViewCar:
ImageView carImageView = (ImageView) view;
byte[] imageBytes = cursor.getBlob(cursor.getColumnIndex("img"));
if (imageBytes != null) { carImageView.setImageBitmap(BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length));
} else {
// carImageView.setBackgroundResource(R.mipmap.ic_launcher);
}
break;
}
return true;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.search , menu);
final MenuItem searchItem = menu.findItem(R.id.action_search);
searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
searchManager = (SearchManager)getActivity().getSystemService(Context.SEARCH_SERVICE); searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
if(searchItem != null){
searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
// some opertion
return true;
}
});
searchView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//some operario
}
});
EditText searchPlate = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
searchPlate.setHint("Search");
View searchPlateView = searchView.findViewById(android.support.v7.appcompat.R.id.search_plate); searchPlateView.setBackgroundColor(ContextCompat.getColor(getActivity(), android.R.color.transparent));
// this method for search process
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
// this method when query submitted
Toast.makeText(getActivity(), s, Toast.LENGTH_SHORT).show();
return true;
}
@Override
public boolean onQueryTextChange(String s) {
// this method for auto complete search process
Toast.makeText(getActivity(), s, Toast.LENGTH_SHORT).show();
myCarSimpleCursorAdapter.getFilter().filter(s); return true;
}
});
}
}
}
For peaple that will have problems with that issue i am posting the best sloution.
Step 1 : Define empty simpleCursor Adapter
public class CarGallery extends ListFragment {
public static final String ROW_ID = "row_id"; // Intent extra key
private SimpleCursorAdapter myCarSimpleCursorAdapter;
private Cursor mCursor;
private String[] from;
private int[] to;
@Override
public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
// map each car details to a TextViews in the ListView layout
from = new String[]{"number", "manufacturer", "model", "img"};
// in file car_row.xml
to = new int[]{R.id.textViewNumber, R.id.textViewManufacturer, R.id.textViewModel, R.id.imageViewCar};
//Create Empty Adapter
myCarSimpleCursorAdapter = new SimpleCursorAdapter(getActivity().getApplicationContext(),
R.layout.car_row, // layout to inflate it
mCursor, // cursor adapter : if null then it will be created within the constructor
from, to, 0);
// set the Adapter on ViewBinder Class
myCarSimpleCursorAdapter.setViewBinder(new MyViewBinder());
setListAdapter(myCarSimpleCursorAdapter); //databinding --> set contactView's adapter
}
Step 2 : Define the Filter method in DatabaseConnector after we created the table :
public class DatabaseConnector //DAL
{
private static final String DATABASE_NAME = "UserCars";
private DatabaseOpenHelper databaseOpenHelper;
private SQLiteDatabase database;
public Cursor getFilteredCars(CharSequence charSequence) {
if (charSequence == null || charSequence.length() == 0) {
return database.rawQuery("SELECT _id ,number, manufacturer , model , img FROM cars order by manufacturer", null);
} else {
String value = "%" + charSequence.toString() + "%";
return database.rawQuery("SELECT _id , number , manufacturer , model ,img FROM cars WHERE manufacturer || number || model like ?", new String[]{value});
}
}
}
Step 3 : Create the Search Widjet on Fragment Class
// creating the SearchView Widjet
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.search, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
if (searchItem != null) {
searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
// some opertion
return true;
}
});
searchView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//some operarion
}
});
EditText searchPlate = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
searchPlate.setHint("Search");
View searchPlateView = searchView.findViewById(android.support.v7.appcompat.R.id.search_plate);
searchPlateView.setBackgroundColor(ContextCompat.getColor(getActivity(), android.R.color.transparent));
// this method for search process
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
// this method when query submitted
myCarSimpleCursorAdapter.getFilter().filter(s);
return true;
}
@Override
public boolean onQueryTextChange(String s) {
// this method for auto complete search process
myCarSimpleCursorAdapter.getFilter().filter(s);
return true;
}
});
}
}
With it"s XML
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".ui.home.activities.TransactionSearchActivity">
<item
android:id="@+id/action_search"
android:icon="@android:drawable/ic_menu_search"
android:title="Search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom" />
</menu>
Step 4 : back to onViewCreate to setFilterQueryProvider , and create the method getCursor
// add this code to onViewCreate
myCarSimpleCursorAdapter.setFilterQueryProvider(new FilterQueryProvider() {
@Override
public Cursor runQuery(CharSequence charSequence) {
return getCursor(charSequence.toString());
// create the getCursor that Include AsyncTask to get data on BackGround
private Cursor getCursor(String str) {
class GetCarTask extends AsyncTask<CharSequence, Object, Cursor> {
DatabaseConnector databaseConnector = new DatabaseConnector(getActivity().getApplicationContext());
@Override
protected Cursor doInBackground(CharSequence... charSequences) {
databaseConnector.open();
return databaseConnector.getFilteredCars(charSequences[0]);
}
@Override
protected void onPostExecute(Cursor cursor) {
super.onPostExecute(cursor);
myCarSimpleCursorAdapter.changeCursor(cursor);
databaseConnector.close();
}
}
new GetCarTask().execute(new CharSequence[]{str});
return null;
} // end of getCursor
Step 5 : Finaly execute the Cursor with null in onResum sending null String wil show all the data befor the filtering and that's it .
@Override
public void onResume() {
super.onResume();
getActivity().setTitle(R.string.actionbarTitleGallery);
mCursor = getCursor("");
}