AutoCompleteTextView отображает неверные строки из SearchRecentSuggestionsProvider с MergeCursor - PullRequest
0 голосов
/ 08 января 2020

Я реализую пользовательский экран поиска в приложении Android, настроил AutoCompleteTextView и установил курсор на мой SearchRecentSuggestionsProvider, чтобы эти предложения отображались для AutoCompleteTextView.

Это работает правильно, когда курсор находится только на SearchRecentSuggestionsProvider, однако я хочу включить некоторые пользовательские предложения, поэтому для этого настроил MergeCursor.

Когда я это делаю, мои пользовательские предложения отображаются правильно, но предложения от SearchRecentSuggestionsProvider отображается как «android .resource: // system / 17301578».

При нажатии на предложение добавляется правильный текст в AutoCompleteTextView, а переход через CursorToStringConverter подтверждает, что они были правильно преобразованы, но по какой-то причине они неправильно отображаются в раскрывающемся списке.

Любая помощь будет принята с благодарностью, поскольку я не смог найти ни одного человека, у которого была похожая проблема, или даже человека y примеры других попыток включить пользовательские предложения в SearchRecentSuggestionsProvider.

Вот код, который добавляет предложения в AutoCompleteTextView:

// Get a cursor to the SearchSuggestionsProvider
val uri =
    Uri.parse("content://" + SearchSuggestionsProvider.AUTHORITY + "/" + SearchManager.SUGGEST_URI_PATH_QUERY)
val projection = arrayOf("_id", SearchManager.SUGGEST_COLUMN_QUERY)
val suggestionCursor =
    this.context?.contentResolver?.query(uri, projection, null, arrayOf(""), null)

// Set up autocomplete for special suggestions
val specialSuggestions = mutableListOf<String>()
specialSuggestions.add("Norfolk Island")
specialSuggestions.add("Pitcairn Island")

// Create a matrix cursor for the new entries, and use a merge cursor to return it with the recent searches
val matrixCursor = MatrixCursor(projection)
for ((i, suggestion) in specialSuggestions.withIndex()) {
    matrixCursor.newRow()
        .add("_id", i)
        .add(SearchManager.SUGGEST_COLUMN_QUERY, suggestion)
}

// Set up the merge cursor
val cursor = MergeCursor(arrayOf(matrixCursor, suggestionCursor))

// Set up an adapter to the cursor
val adapter = SimpleCursorAdapter(
    this.context,
    android.R.layout.simple_list_item_1,
    cursor,
    arrayOf(SearchManager.SUGGEST_COLUMN_QUERY),
    intArrayOf(android.R.id.text1),
    SearchManager.FLAG_QUERY_REFINEMENT
)

// This ensures that the row in the cursor is returned as the suggestion string
adapter.cursorToStringConverter = SimpleCursorAdapter.CursorToStringConverter { cur ->
    cur.getString(cur.getColumnIndexOrThrow(SearchManager.SUGGEST_COLUMN_QUERY))
}

// This adds filtering based on what the user has typed
adapter.filterQueryProvider = FilterQueryProvider { text ->
    val filterSuggestionCursor = this.context?.contentResolver?.query(
        uri,
        projection,
        null,
        arrayOf(text.toString()),
        null
    )
    val filterMatrixCursor = MatrixCursor(projection)
    for ((i, suggestion) in specialSuggestions.filter { s -> s.contains(text, true) }.withIndex()) {
        filterMatrixCursor.newRow()
            .add("_id", i)
            .add(SearchManager.SUGGEST_COLUMN_QUERY, suggestion)
    }
    MergeCursor(arrayOf(filterMatrixCursor, filterSuggestionCursor))
}

// Add the adapter to the AutoCompleteTextView
val keywordsInput = view.findViewById<AutoCompleteTextView>(R.id.search_keywords_input)
keywordsInput.setAdapter(adapter)

Вот часть представления для поля поиска:

<com.google.android.material.textfield.TextInputLayout
    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginEnd="16dp"
    android:layout_marginStart="16dp"
    android:layout_marginTop="16dp"
    android:hint="Add Search Keywords..."
    app:endIconCheckable="true"
    android:id="@+id/search_keywords"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:endIconDrawable="@android:drawable/ic_input_add"
    app:endIconMode="custom"
    app:endIconTint="@color/colorPrimaryDark"
    app:endIconContentDescription="Add Keyword">

    <androidx.appcompat.widget.AppCompatAutoCompleteTextView
        style="@style/Widget.MaterialComponents.AutoCompleteTextView.OutlinedBox.Dense"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:completionThreshold="1"
        android:maxLines="1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:id="@+id/search_keywords_input" />

</com.google.android.material.textfield.TextInputLayout>

Вот скриншот ошибки в действии:

Screenshot showing the issue

1 Ответ

0 голосов
/ 08 января 2020

Кажется, что когда вы используете MergeCursor с вашим MatrixCursor и SearchRecentSuggestionsProvider, вам нужны все столбцы из SearchRecentSuggestionsProvider, и в том же порядке.

Впоследствии проекция SearchRecentSuggestionsProvider применяется, кажется ( Я думал, что MergeCursor объединит проекцию с моим MatrixCursor).

Чтобы решить эту проблему, я изменил конструктор MatrixCursor на:

val filterMatrixCursor = MatrixCursor(filterSuggestionCursor?.columnNames)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...