如何使用 ListFragment 上的 SearchView 小部件进行过滤
how to Filter by Using SearcheView Widjet on ListFragment
您好,我在谷歌上搜索了很长时间但没有解决方案
我有 ListFragment 显示来自 SQlite 的数据
我想构建按 TextChange 过滤的选项
我添加了 widjet 及其完美的工作 - 但如何制作过滤器??
getFilter().filter() 是不够的。
这是片段列表
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;
}
});
}
}
}
对于那些在该问题上有问题的人,我发布了最好的解决方案。
第 1 步:定义空的 simpleCursor 适配器
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
}
第 2 步:在我们创建 table :
之后,在 DatabaseConnector 中定义 Filter 方法
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});
}
}
}
第 3 步:在片段上创建搜索 Widjet 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;
}
});
}
}
有了它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>
第 4 步:返回 onViewCreate 到 setFilterQueryProvider,并创建方法 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
第 5 步:最后在 onResum 中执行带有 null 的 Cursor,发送 null String 将显示过滤前的所有数据
就是这样。
@Override
public void onResume() {
super.onResume();
getActivity().setTitle(R.string.actionbarTitleGallery);
mCursor = getCursor("");
}
您好,我在谷歌上搜索了很长时间但没有解决方案 我有 ListFragment 显示来自 SQlite 的数据 我想构建按 TextChange 过滤的选项 我添加了 widjet 及其完美的工作 - 但如何制作过滤器?? getFilter().filter() 是不够的。
这是片段列表
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;
}
});
}
}
}
对于那些在该问题上有问题的人,我发布了最好的解决方案。
第 1 步:定义空的 simpleCursor 适配器
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
}
第 2 步:在我们创建 table :
之后,在 DatabaseConnector 中定义 Filter 方法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});
}
}
}
第 3 步:在片段上创建搜索 Widjet 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;
}
});
}
}
有了它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>
第 4 步:返回 onViewCreate 到 setFilterQueryProvider,并创建方法 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
第 5 步:最后在 onResum 中执行带有 null 的 Cursor,发送 null String 将显示过滤前的所有数据 就是这样。
@Override
public void onResume() {
super.onResume();
getActivity().setTitle(R.string.actionbarTitleGallery);
mCursor = getCursor("");
}