2

カスタム検索ボックスの候補を表示しようとしていますが、表示される結果が空です。この機能を実装するために、いくつかのガイドに従いました。

これにより、次のコードが生成されました。

検索ボックスの追加:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getSupportMenuInflater().inflate(R.menu.building_search, menu);

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = new SearchView(getSupportActionBar().getThemedContext());

    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setSuggestionsAdapter(new BuildingSuggestionsAdapter(this, searchManager.getSearchableInfo(getComponentName()), searchView));

    return super.onCreateOptionsMenu(menu);
}

建物をデータベースに追加する:

for (Resto resto : restos) {
    ContentValues values = new ContentValues();
    values.put(TableBuildings.Buildings.NAME, resto.name);
    values.put(TableBuildings.Buildings.DISTANCE, "3");
    getContentResolver().insert(TableBuildings.Buildings.CONTENT_URI, values);
}

BuildingSuggestionAdapter:

public class BuildingSuggestionsAdapter extends CursorAdapter {

    private static final int QUERY_LIMIT = 50;
    private LayoutInflater inflater;
    private SearchView searchView;
    private SearchableInfo searchable;

    public BuildingSuggestionsAdapter(Context context, SearchableInfo info, SearchView searchView) {
        super(context, null, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
        this.searchable = info;
        this.searchView = searchView;
        this.inflater = LayoutInflater.from(context);
    }

    @Override
    public void bindView(View v, Context context, Cursor c) {
        String name = c.getString(c.getColumnIndex(TableBuildings.Buildings.NAME));
        TextView namet = (TextView) v.findViewById(R.id.resto_search_name);
        namet.setText(name);

        String man = c.getString(c.getColumnIndex(TableBuildings.Buildings.DISTANCE));
        TextView manuf = (TextView) v.findViewById(R.id.resto_search_distance);
        manuf.setText(man);

        Toast.makeText(context, name + " " + man, Toast.LENGTH_LONG).show();
    }

    @Override
    public View newView(Context arg0, Cursor arg1, ViewGroup arg2) {
        return this.inflater.inflate(R.layout.resto_search_suggestion_view, null);
    }

    /**
     * Use the search suggestions provider to obtain a live cursor. This will be called in a worker
     * thread, so it's OK if the query is slow (e.g. round trip for suggestions). The results will
     * be processed in the UI thread and changeCursor() will be called.
     */
    @Override
    public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
        String query = (constraint == null) ? "" : constraint.toString();
        /**
         * for in app search we show the progress spinner until the cursor is returned with the
         * results.
         */
        Cursor cursor = null;
        if (searchView.getVisibility() != View.VISIBLE
            || searchView.getWindowVisibility() != View.VISIBLE) {
            return null;
        }
        try {
            cursor = getSuggestions(searchable, query, QUERY_LIMIT);
            // trigger fill window so the spinner stays up until the results are copied over and
            // closer to being ready
            if (cursor != null) {
                cursor.getCount();
                return cursor;
            }
        } catch (RuntimeException e) {
        }
        // If cursor is null or an exception was thrown, stop the spinner and return null.
        // changeCursor doesn't get called if cursor is null
        return null;
    }


    public Cursor getSuggestions(SearchableInfo searchable, String query, int limit) {

        if (searchable == null) {
            return null;
        }

        String authority = searchable.getSuggestAuthority();
        if (authority == null) {
            return null;
        }

        Uri.Builder uriBuilder = new Uri.Builder()
            .scheme(ContentResolver.SCHEME_CONTENT)
            .authority(authority)
            .query("")
            .fragment("");

        // if content path provided, insert it now
        final String contentPath = searchable.getSuggestPath();
        if (contentPath != null) {
            uriBuilder.appendEncodedPath(contentPath);
        }

        // append standard suggestion query path
        uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY);

        // get the query selection, may be null
        String selection = searchable.getSuggestSelection();
        // inject query, either as selection args or inline
        String[] selArgs = null;
        if (selection != null) {    // use selection if provided
            selArgs = new String[]{query};
        } else {                    // no selection, use REST pattern
            uriBuilder.appendPath(query);
        }

        if (limit > 0) {
            uriBuilder.appendQueryParameter("limit", String.valueOf(limit));
        }

        Uri uri = uriBuilder.build();

        // finally, make the query
        return mContext.getContentResolver().query(uri, null, selection, selArgs, null);
    }
}

プロバイダー:

public class BuildingSuggestionProvider extends ContentProvider {

    private SQLiteDatabase sqlDB;
    private DatabaseHelper dbHelper;
    private static final String DATABASE_NAME = "Buildings.db";
    private static final int DATABASE_VERSION = 1;
    private static final String TABLE_NAME = "Buildings";

    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            //create table to store user names
            db.execSQL("Create table " + TABLE_NAME + "( _id INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, DISTANCE TEXT);");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
            onCreate(db);
        }
    }

    @Override
    public int delete(Uri uri, String s, String[] as) {
        return 0;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues contentvalues) {
        // get database to insert records
        sqlDB = dbHelper.getWritableDatabase();
        // insert record in user table and get the row number of recently inserted record
        long rowId = sqlDB.insert(TABLE_NAME, "", contentvalues);
        if (rowId > 0) {
            Uri rowUri = ContentUris.appendId(TableBuildings.Buildings.CONTENT_URI.buildUpon(), rowId).build();
            getContext().getContentResolver().notifyChange(rowUri, null);
            return rowUri;
        }
        throw new SQLException("Failed to insert row into " + uri);
    }

    @Override
    public boolean onCreate() {
        dbHelper = new DatabaseHelper(getContext());
        return (dbHelper == null) ? false : true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        qb.setTables(TABLE_NAME);
        Cursor c = qb.query(db, projection, selection, null, null, null, sortOrder);
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }

    @Override
    public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {
        return 0;
    }
}

テーブルビルディング:

import android.net.Uri;
import android.provider.BaseColumns;
public class TableBuildings {

    public static final String AUTHORITY = "be.ugent.zeus.hydra.ui.map.suggestions.BuildingSuggestionProvider";

    // BaseColumn contains _id.
    public static final class Buildings implements BaseColumns {

        public static final Uri CONTENT_URI = Uri.parse("content://be.ugent.zeus.hydra.ui.map.suggestions.BuildingSuggestionProvider");
        // Table column
        public static final String NAME = "NAME";
        public static final String DISTANCE = "DISTANCE";
    }
}

最後に、検索ボックスを定義するために使用される XML と、アプリケーションのプロバイダーに使用される xml が続きます。

<?xml version="1.0" encoding="UTF-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
            android:label="@string/resto_search_label"
            android:hint="@string/resto_search_hint" 
            android:searchSuggestAuthority="be.ugent.zeus.hydra.ui.map.suggestions.BuildingSuggestionProvider" />



<provider
            android:name=".ui.map.suggestions.BuildingSuggestionProvider"
            android:authorities="be.ugent.zeus.hydra.ui.map.suggestions.BuildingSuggestionProvider" />

私が得た結果は次のとおりです。エラーはありません。検索ビューを開き、コンテンツ プロバイダーにクエリを実行します。奇妙な部分は、プロバイダーのクエリ メソッドが呼び出されることですが、アダプターからは呼び出されません。たとえば、ブレークポイントを配置しても、プログラムが停止しません。視覚的には、キーボードがポップアップしてリストが表示されますが、リストには空のアイテムしか含まれていません...

誰にもアイデアはありますか?

前もって感謝します。

4

1 に答える 1