如何使用 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("");
}