androidx searchview не показывает предложения запроса - PullRequest
0 голосов
/ 03 августа 2020

У меня есть 2 копии одного и того же проекта. Рабочий с предложениями использует android поддержку searchView (android .support.v7.widget.SearchView), а проект, который использует (androidx.appcompat.widget.searchview), не показывает предложения.

Что я могу сделать, чтобы это исправить.

AndroidManifest. xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.earthquakeclone">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".EarthquakeSearchResultActivity"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
            </intent-filter>
            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable"/>
        </activity>
        <activity android:name=".PreferenceActivity">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data
                android:name="android.app.default_searchable"
                android:value=".EarthquakeSearchResultActivity"/>
        </activity>

        <provider
            android:name=".EarthquakeSearchProvider"
            android:authorities="com.example.provider.earthquakeclone" />
    </application>

</manifest>

меню. xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/settings_menu_item"
        android:title="Settings" />
    <item android:id="@+id/search_view"
        android:title="@string/search_label"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="androidx.appcompat.widget.SearchView" />
</menu>

mainactivity. java

public class MainActivity extends AppCompatActivity implements EarthquakeListFragment.OnSwipeRefreshListener{

    EarthquakeListFragment mEarthquakeListFragment;
    public static final String TAG_FRAGMENT = "TAG_FRAGMENT";
    public static final int MENU_PREFERENCE = Menu.FIRST -1;
    private static final int SHOW_PREFERENCES = 1;
    EarthquakeViewModel mEarthquakeViewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fragmentManager = getSupportFragmentManager();

        if(savedInstanceState == null) {
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            mEarthquakeListFragment = new EarthquakeListFragment();
            fragmentTransaction.add(R.id.main_activity_frame, mEarthquakeListFragment, TAG_FRAGMENT);
            fragmentTransaction.commitNow();
        } else {
            mEarthquakeListFragment = (EarthquakeListFragment) fragmentManager.findFragmentByTag(TAG_FRAGMENT);
        }

        mEarthquakeViewModel = ViewModelProviders.of(this).get(EarthquakeViewModel.class);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.options_menu, menu);

        SearchManager searchManager =
                (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        SearchableInfo searchableInfo = searchManager.getSearchableInfo( new ComponentName(getApplicationContext(), EarthquakeSearchResultActivity.class));

        SearchView searchView = (SearchView) menu.findItem(R.id.search_view).getActionView();
        searchView.setSearchableInfo(searchableInfo);
        searchView.setIconifiedByDefault(false);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.settings_menu_item:
                Intent intent = new Intent(this, PreferenceActivity.class);
                startActivityForResult(intent, SHOW_PREFERENCES);
                return true;
        }
        return false;
    }

    @Override
    public void onSwipe() {
        loadEarthquakes();
    }

    void loadEarthquakes() {
        mEarthquakeViewModel.loadEarthquakes();
    }

}

EarthqaukeSearchProvider. java

public class EarthquakeSearchProvider extends ContentProvider {

    private static final UriMatcher uriMatcher;
    public static final int SEARCH_SUGGESTIONS = 1;

    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("com.example.provider.earthquakeclone", SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGESTIONS);
        uriMatcher.addURI("com.example.provider.earthquakeclone" + "/*", SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGESTIONS);
        uriMatcher.addURI("com.example.provider.earthquakeclone", SearchManager.SUGGEST_URI_PATH_SHORTCUT, SEARCH_SUGGESTIONS);
        uriMatcher.addURI("com.example.provider.earthquakeclone", SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/*", SEARCH_SUGGESTIONS);
    }

    @Override
    public boolean onCreate() {
        EarthquakeDatabaseAccessor.getInstance(getContext().getApplicationContext());
        return true;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s, @Nullable String[] strings1, @Nullable String s1) {
        if(uriMatcher.match(uri) == SEARCH_SUGGESTIONS) {
            String searchQuery = "%" + uri.getLastPathSegment() + "%";
            EarthquakeDAO earthquakeDAO = EarthquakeDatabaseAccessor.getInstance(getContext().getApplicationContext()).earthquakeDAO();
            Cursor c = earthquakeDAO.generateSearchSuggestions(searchQuery);

            return c;
        }

        return null;
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        switch (uriMatcher.match(uri)) {
            case SEARCH_SUGGESTIONS:
                return SearchManager.SUGGEST_MIME_TYPE;
            default:
                throw new IllegalArgumentException("Unsupported URi: " + uri);
        }
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
        return null;
    }

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

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
        return 0;
    }
}

earthquakeSearchResultActivity. java

public class EarthquakeSearchResultActivity extends AppCompatActivity {

    private ArrayList<Earthquake> mEarthquakes = new ArrayList< >();
    private EarthquakeRecyclerAdapter mEarthquakeAdapter = new EarthquakeRecyclerAdapter(mEarthquakes);
    private MutableLiveData<String> searchQuery;
    private LiveData<List<Earthquake>> searchResults;
    private MutableLiveData<String> selectedSearchSuggestionId;
    private LiveData<Earthquake> selectedSearchSuggestion;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_earthquake_search_result);

        RecyclerView recyclerView = findViewById(R.id.search_result_list);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(mEarthquakeAdapter);

        // Initialize the search query Live Data.
        searchQuery = new MutableLiveData<>();
        searchQuery.setValue(null);

        // Link the search query Live Data to the search results Live Data.
        // Configure Switch Map such that a change in the search query
        // updates the search results by querying the database.
        searchResults = Transformations.switchMap(searchQuery,
                query -> EarthquakeDatabaseAccessor.getInstance(getApplicationContext()).earthquakeDAO().searchEarthquakes("%" + query + "%"));

        // Observe changes to the search results Live Data.
        searchResults.observe(EarthquakeSearchResultActivity.this,
                searchQueryResultObserver);

        // Initialize the selected search suggestion Id Live Data.
        selectedSearchSuggestionId = new MutableLiveData<>();
        selectedSearchSuggestionId.setValue(null);

        // Link the selected search suggestion ID Live Data to the
        // selected search suggestion Live Data.
        // Configure Switch Map such that a change in the ID of the
        // selected search suggestion, updates the Live Data that
        // returns the corresponding Earthquake by querying the database.
        selectedSearchSuggestion =
                Transformations.switchMap(selectedSearchSuggestionId,
                        id -> EarthquakeDatabaseAccessor.getInstance(getApplicationContext()).earthquakeDAO().getEarthquake(id));

        // If the Activity was launched by a search suggestion
        if (Intent.ACTION_VIEW.equals(getIntent().getAction())) {
            selectedSearchSuggestion.observe(this,
                    selectedSearchSuggestionObserver);
            setSelectedSearchSuggestion(getIntent().getData());
        }
        else {
            // If the Activity was launched from a search query,
            // extract the search query term and update the search query
            // Live Data.
            String query = getIntent().getStringExtra(SearchManager.QUERY);
            setSearchQuery(query);
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        // If the search Activity exists, and another search
        // is performed, set the launch Intent to the newly
        // received search Intent.
        setIntent(intent);

        if (Intent.ACTION_VIEW.equals(getIntent().getAction())) {
            // Update the selected search suggestion Id.
            setSelectedSearchSuggestion(getIntent().getData());
        }
        else {
            // Extract the search query and update the searchQuery Live Data.
            String query = getIntent().getStringExtra(SearchManager.QUERY);
            setSearchQuery(query);
        }
    }

    private void setSearchQuery(String query) {
        searchQuery.setValue(query);
    }

    private final Observer<List<Earthquake>> searchQueryResultObserver
            = updatedEarthquakes -> {
        // Update the UI with the updated search query results.
        mEarthquakes.clear();

        if (updatedEarthquakes != null)
            mEarthquakes.addAll(updatedEarthquakes);

        mEarthquakeAdapter.notifyDataSetChanged();
    };

    private void setSelectedSearchSuggestion(Uri dataString) {
        String id = dataString.getPathSegments().get(1);
        selectedSearchSuggestionId.setValue(id);
    }

    final Observer<Earthquake> selectedSearchSuggestionObserver
            = selectedSearchSuggestion -> {
        // Update the search query to match the selected search suggestion.
        if (selectedSearchSuggestion != null) {
            setSearchQuery(selectedSearchSuggestion.getDetails());
        }
    };
}

earthquakeDAO

@Dao
public interface EarthquakeDAO {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    public void insertEarthquakes(List<Earthquake> earthquakes);

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    public void insertEarthquake(Earthquake earthquake);

    @Query("SELECT * FROM earthquake ORDER BY mDate DESC")
    public LiveData<List<Earthquake>> loadAllEarthquakes();

    @Query("SELECT mId as _ID, " + "mDetails as suggest_text_1, " + "mId as suggest_intent_data_id " + "FROM earthquake " + "WHERE mDetails LIKE:query " + "ORDER BY mDate DESC")
    public Cursor generateSearchSuggestions(String query);

    @Query("SELECT * FROM earthquake WHERE mDetails LIKE:query ORDER BY mDate DESC")
    public LiveData<List<Earthquake>> searchEarthquakes(String query);

    @Delete
    public void deleteEarthquake(Earthquake earthquake);

    @Query("SELECT * FROM earthquake WHERE mId = :id LIMIT 1")
    public LiveData<Earthquake> getEarthquake(String id);
}

полный исходник для рабочего проекта

ЗДЕСЬ

введите описание изображения здесь

...