У меня есть 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);
}
полный исходник для рабочего проекта
ЗДЕСЬ
введите описание изображения здесь