Android SearchView:将数据传递给详细信息

时间:2016-04-16 13:27:53

标签: android sqlite search android-contentprovider

我正在关注this tutorial以在我的工具栏中创建搜索视图。我想要的是当我点击其中一个搜索结果项目时,我想在细节活动中显示其相应的数据,但我似乎无法实现。

这是我的代码:

MainActivity类:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_search, menu);

        MenuItem searchItem = menu.findItem(R.id.search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
        searchView.setOnQueryTextListener(this);

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView.setSearchableInfo(searchManager.getSearchableInfo(
                new ComponentName(this, SearchableActivity.class)));
        searchView.setIconifiedByDefault(false);

        return true;
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            Toast.makeText(this, "Searching by: "+ query, Toast.LENGTH_SHORT).show();

        } else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
            String uri = intent.getDataString();
            Toast.makeText(this, "Suggestion: "+ uri, Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        // User pressed the search button
        return false;
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        // User changed the text
        return false;
    }

SearchableActivity类:

public class SearchableActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_searchable);
        TextView txt = (TextView)findViewById(R.id.textView);

        Intent intent = getIntent();
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            txt.setText("Searching by: "+ query);

        } else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
            String uri = intent.getDataString();
            txt.setText("Suggestion: "+ uri);

        }
    }

CitySuggestionProvider类:

public class CitySuggestionProvider extends ContentProvider {

    List<String> cities;

    @Override
    public boolean onCreate() {
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        if (cities == null || cities.isEmpty()){
            Log.d("NGVL", "WEB");
            List<CityPojo> pojos = new ArrayList<>();
            cities = new ArrayList<>();
            DatabaseHelper db = new DatabaseHelper(getContext());

            try {

                try {
                    db.create();
                } catch (IOException ioe) {
                    throw new Error("Unable to create database");
                }

                if (db.open()) {
                    pojos = db.getCities();
                }
                db.close();



                int lenght = pojos.size();
                for (int i = 0; i < lenght; i++) {
                    String city = pojos.get(i).getCity();
                    cities.add(city);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            Log.d("NGVL", "Cache!");
        }

        MatrixCursor cursor = new MatrixCursor(
                new String[] {
                        BaseColumns._ID,
                        SearchManager.SUGGEST_COLUMN_TEXT_1,
                        SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID
                }
        );
        if (cities != null) {
            String query = uri.getLastPathSegment().toUpperCase();
            int limit = Integer.parseInt(uri.getQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT));

            int lenght = cities.size();
            for (int i = 0; i < lenght && cursor.getCount() < limit; i++) {
                String city = cities.get(i);
                if (city.toUpperCase().contains(query)){
                    cursor.addRow(new Object[]{ i, city, i });
                }
            }
        }
        return cursor;
    }


}

清单:

<activity
            android:name=".MainActivity"
            android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <provider
            android:name=".CitySuggestionProvider"
            android:authorities="ngvl.android.demosearch.citysuggestion"
            android:enabled="true"
            android:exported="true"/>

        <activity android:name=".SearchableActivity">
            <intent-filter>
                <action android:name="android.intent.action.SEARCH"/>
            </intent-filter>
            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable"/>
        </activity>

searchable.xml:

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
            android:hint="@string/hint_search"
            android:label="@string/app_name"
            android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
            android:searchSuggestAuthority="ngvl.android.demosearch.citysuggestion"
            android:searchSuggestIntentAction="android.intent.action.VIEW"
            android:searchSuggestIntentData="content://ngvl.android.demosearch.city"/>

Everthing工作正常我得到的结果就像这张图片一样:

enter image description here

但问题是,当我点击建议时,我想在另一个活动中显示其详细信息。我有2个文本字段:城市和国家,因此当用户在建议中单击城市时,我想在详细信息活动中显示其对应的国家/地区。我不确定如何将国家/地区数据传递给详细信息活动。我正在使用SQLite来获取内容提供程序类中的数据

1 个答案:

答案 0 :(得分:0)

我是上述教程的作者:) 首先,对不起,样本不够清楚,让我试着更好地解释一下。

示例中描述的内容提供商应仅提供搜索建议。因此,当用户在列表中选择一个选项时,Uri将返回(在大多数情况下)另一个提供者。请注意,在可搜索的配置文件( res / xml / searchable.xml )中有以下属性:

content://ngvl.android.demosearch.city

因此,您应该有一个内容提供商来参加此Uri并返回有关用户选择的所有详细信息。出于这个原因,我只在第二个活动(SearchableActivity.java)中显示Uri。

然而,我更新代码来回答你的问题:)现在建议提供商正在回答两个Uris :) 这是提交的链接。 https://github.com/nglauber/playground/commit/51741babd301b42be220fc771c563da660808b20

如果您有任何问题,请告诉我们。)

希望它有所帮助!