2017-10-26 6 views
0

私は、ユーザーがワインのデータベースを検索できるように努力しているアクションバーSearchViewを持っています。SearchViewを使用してSQLiteデータベースを検索する

「na」と入力した場合のように、「na」を含むすべての結果が表示されるように、ユーザーが入力する間に検索するようにしています。ここで

は私のメニューの検索ボタンは、if文です:

if (id == R.id.action_wine_search) { 
     SearchView searchView = getActivity().findViewById(R.id.action_wine_search); 
     searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 
      @Override 
      public boolean onQueryTextSubmit(String newText) { 
       return false; 
      } 

      @Override 
      public boolean onQueryTextChange(String newText) { 
       mCursorAdapter.getFilter().filter(newText); 
       //mCursorAdapter is selecting id,name,price,etc. columns from the table 
       wineListView.setAdapter(mCursorAdapter); 

       return false; 
      } 
     }); 
    } 

私はそれを理解できるように(私は間違った方法でこれを考えることかもしれない)フィルターがSearchViewからテキストを取得しているということで、そのテキストをCursorAdapterに適用しています。

これは何もしていません。あなたが何を入力してもリストはまったく変わりません。

私はこのためにyoutubeビデオに続きました。私はそれがどのようにCursorAdapterに適用されていたかはかなり分かりません。

私は(これも失敗し、リストは全く変わりません)自分でそれをしようとしてしまった:

public boolean onQueryTextChange(String newText) { 

       SQLiteDatabase db = mDatabaseHelper.getReadableDatabase(); 

       //Selecting what details I want to put into each row in the list 
       String[] projection = { 
         WineContract.WineEntry.COLUMN_ID, 
         WineContract.WineEntry.COLUMN_WINE_NAME, 
         WineContract.WineEntry.COLUMN_WINE_PRICE, 
         WineContract.WineEntry.COLUMN_WINE_RATING, 
         WineContract.WineEntry.COLUMN_WINE_STORE, 
         WineContract.WineEntry.COLUMN_WINE_IMAGE, 
         WineContract.WineEntry.COLUMN_WINE_THUMBNAIL}; 

       //I want to return the row where the name is equal to newText (which is what the user types into the SearchView 
       String selection = WineContract.WineEntry.COLUMN_WINE_NAME + " = ?"; 
       String[] selectionArgs = {newText}; 

       Cursor cursor = db.query(WineContract.WineEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); 
       mCursorAdapter = new WineCursorAdapter(getActivity(), cursor); 
       wineListView.setAdapter(mCursorAdapter); 

       return false; 
      } 
     }); 

は、私は、これは動作するようになっている方法を理解する上でいくつかの助けを得ることができますか?

+0

、あなたはいくつかの簡単なリストラを行う必要があります。 (1) 'ListView'のために' WineCursorAdapter'を1つ作成し、 'Cursor'を変更する' changeCursor(Cursor) 'メソッドを使用します。ユーザーが新しい文字を入力するたびにまったく新しい' WineCursorAdapter'を作成しないでください。それはあまり効率的ではありません! (2)これを実行することでメインのUIスレッドをブロックするので(吃音の原因になる)、AsyncTaskまたは他のスレッドでデータベースクエリを実行する必要があります。 – Brian

+0

あなたの本来の目標では、あなたがフォローしているこのYouTube動画をリンクできますか?私は検索結果を検索/フィルタリングするために以前は 'Cursor'フィルタを使っていませんでしたが、もっと学ぶために興味を持っています。 – Brian

+0

これは私が言及したビデオへのリンクです:https://www.youtube.com/watch?v=4RfvmrelFzE – andrdoiddev

答えて

1

あなたがリンクしたビデオを見ましたが、残念ながら、ビデオはこの検索機能をかなり異なるアプローチで実現する方法を示しているようです。つまり、Filterの組み込みの実装をいくつか持っているArrayAdapter<String>を使用すると、単純な結果リストで部分文字列マッチングを実行できるようになります。

CursorAdapterを使用してデータベースを検索した場合、残念ながらこの方法では機能しません。 CursorAdapterは、Cursorオブジェクトを返します。このオブジェクトは、実際にはデータベースクエリによって返された行データ/結果を取得するための「ファサード」です。言い換えれば、CursorAdapterは何も「フィルタリング」する方法を知らないので、フィルタが適用されたときに何をすべきかを指定する必要があります。たとえば、あなたがこのような何かを実装する必要があります:

adapter.setFilterQueryProvider(new FilterQueryProvider() { 
    @Override 
    public Cursor runQuery(CharSequence query) { 
     // Run some database query, given this "query" String and return a Cursor 
     return searchDatabase(query); 
    } 
}); 

あなたは一種の右の考え方に検索クエリを実装するコードの2番目のスニペットを持っていました。しかし、標準のSQLiteデータベーステーブルでは、の正確なの条件(基本的には上記のコードは基本的には一致しています)に一致する行を検索することができます。

幸いにも、SQLiteデータベースで全文検索を行う方法がありますので、部分文字列や部分的なクエリ(おそらくなど)を検索して一致させることができます。検索をサポートするために、FTS3などのスキームを実装するSQLite仮想テーブルと呼ばれるものを使用できます。

https://developer.android.com/training/search/search.html

私はデータベース全体で検索を実行するために、過去数回でこのメソッドを使用しました。これを実現する方法を正確にあなたが表示されますその下にリンクされ、公式のAndroidドキュメント上の偉大なチュートリアルがあります。おそらくあなたの現在のデータベースヘルパーを変更すると予想されるよりももう少し仕事があるでしょうが、これは私がそれを行う方法を知っている方法です。何かが意味をなさないと私に教えてください!

また、コードを再構成することに関する上記のコメントを考慮に入れたいと思います。なぜなら、良いパフォーマンスを考慮したアプリケーションを作成したいと思うからです!

0

私が似たようなことをしているのかどうか分からないのは、単にクエリを駆動し、更新されたカーソルを取得し、ListViewアダプタでswapCursorを使用するtextChangedListenerを持つEditTextを持つことです。クエリ自体はLikeを使用してすべての発生を取得します。それはNAを持っています。

このリスナーのセットアップコード: -

/************************************************************************** 
* addFilterListener - Add a Listener to filter the ListView 
*      i.e. as characters are typed then the ListView 
*      is filtered according to the characters input 
*      This is done by using LIKE '%<characters>%' 
* 
*/ 
public void addFilterListener() { 

    inputproductfilter.addTextChangedListener(new TextWatcher() { 
     @Override 
     public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 

     } 

     @Override 
     public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 
      productfilter = DBProductsTableConstants.PRODUCTS_NAME_COL_FULL + 
        SQLLIKECHARSTART + 
        inputproductfilter.getText().toString() + 
        SQLLIKECHAREND; 
      plcsr = dbproductmethods.getExpandedProducts(productfilter,orderby); 
      productlistadapter.swapCursor(plcsr); 
     } 

     @Override 
     public void afterTextChanged(Editable editable) { 

     } 
    }); 
} 

それは使用しています: -

public static final String SQLLIKECHARSTART = " LIKE '%"; 
public static final String SQLLIKECHAREND = "%' "; 

とNot

以下
public static final String SQLAS = " AS "; 

のために、それはすべて、関連するが、ここでgetExpandedproductsだということ。 -

/************************************************************************** 
* 
* @param filter filter string less WHERE keyword 
* @param order  order String less ORDER and BY kewords 
* @return   Cursor containing Expanded products 
*/ 
Cursor getExpandedProducts(String filter, String order) { 
    Cursor rv; 
    String[] columns = new String[] { 
      DBProductsTableConstants.PRODUCTS_ID_COL_FULL, 
      DBProductsTableConstants.PRODUCTS_NAME_COL_FULL, 
      DBProductsTableConstants.PRODUCTS_NOTES_COL_FULL, 
      DBProductsTableConstants.PRODUCTS_STORAGEORDER_COL_FULL, 
      DBProductsTableConstants.PRODUCTS_STORAGEREF_COL_FULL, 
      DBStorageTableConstants.STORAGE_ID_COL_FULL + 
        SQLAS + DBStorageTableConstants.STORAGE_ALTID_COL, 
      DBStorageTableConstants.STORAGE_NAME_COL_FULL, 
      DBStorageTableConstants.STORAGE_ORDER_COL_FULL 
    }; 
    String table = DBProductsTableConstants.PRODUCTS_TABLE + 
      SQLLEFTJOIN + 
      DBStorageTableConstants.STORAGE_TABLE + 
      SQLON + 
      DBProductsTableConstants.PRODUCTS_STORAGEREF_COL_FULL + 
      " = " + 
      DBStorageTableConstants.STORAGE_ID_COL_FULL; 
    rv = db.query(table,columns,filter,null,null,null,order); 
    return rv; 
} 

完全なリスト: -

enter image description here

、その後フィルタに入力された NAで: - 何かする前に

enter image description here

関連する問題