42

我在操作栏中使用 SearchView。我想在搜索视图上使用自动完成功能从数据库中获取结果。

这可能吗?还是我需要使用自定义文本框,然后添加自动完成?

4

7 回答 7

41

所以我只需要为 v7 版本执行此操作,并且很沮丧地发现我不能简单地使用 ArrayAdapter 设置适配器。

我不想使用股票 AutoCompleteTextView(就像这里的顶级评论者那样),因为那样你就会错过 SearchView 的许多时髦功能,比如小搜索图标和 x 按钮。

所以我扩展了 SearchView 并得到了这个:

public class ArrayAdapterSearchView extends SearchView {

private SearchView.SearchAutoComplete mSearchAutoComplete;

public ArrayAdapterSearchView(Context context) {
    super(context);
    initialize();
}

public ArrayAdapterSearchView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public void initialize() {
    mSearchAutoComplete = (SearchAutoComplete) findViewById(android.support.v7.appcompat.R.id.search_src_text);
    this.setAdapter(null);
    this.setOnItemClickListener(null);
}

@Override
public void setSuggestionsAdapter(CursorAdapter adapter) {
    // don't let anyone touch this
}

public void setOnItemClickListener(OnItemClickListener listener) {
    mSearchAutoComplete.setOnItemClickListener(listener);
}

public void setAdapter(ArrayAdapter<?> adapter) {
    mSearchAutoComplete.setAdapter(adapter);
}

public void setText(String text) {
    mSearchAutoComplete.setText(text);
}

}

您可以在 ActionBar 的菜单 xml 中使用它,如下所示:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" >

<item
    android:id="@+id/action_search"
    android:icon="@android:drawable/ic_menu_add"
    android:title="TITLE"
    app:actionViewClass="com.yourpackage.ArrayAdapterSearchView"
    app:showAsAction="ifRoom|collapseActionView"/>

</menu>

您可能还想将点击功能添加到自动完成列表(例如,将文本设置为 EditText):

MenuItem searchItem = menu.findItem(R.id.action_search);
final ArrayAdapterSearchView searchView = (ArrayAdapterSearchView)searchItem.getActionView();
searchView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        searchView.setText(adapter.getItem(position).toString());

    }
});

这是常规旧 android.widget.SearchView 的类似版本:

public class ArrayAdapterSearchView extends SearchView {

private AutoCompleteTextView mSearchAutoComplete;

public ArrayAdapterSearchView(Context context) {
    super(context);
    initialize();
}

public ArrayAdapterSearchView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public void initialize() {
    mSearchAutoComplete = (AutoCompleteTextView) findViewById(getResources().getIdentifier("android:id/search_src_text", null, null));
    setAutoCompleSuggestionsAdapter(null);
    setOnItemClickListener(null);
}

@Override
public void setSuggestionsAdapter(CursorAdapter adapter) {
    throw new UnsupportedOperationException("Please use setAutoCompleSuggestionsAdapter(ArrayAdapter<?> adapter) instead");
}

public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
    mSearchAutoComplete.setOnItemClickListener(listener);
}

public void setAutoCompleSuggestionsAdapter(ArrayAdapter<?> adapter) {
    mSearchAutoComplete.setAdapter(adapter);
}

public void setText(String text) {
    mSearchAutoComplete.setText(text);
}

}
于 2013-11-15T00:01:40.127 回答
36

我已经使用自定义 AutoCompleteTextView 并将其添加到 ActionBar 中。

在此处输入图像描述

public class MainActivity extends Activity {

    private static final String[] COUNTRIES = new String[] { "Belgium",
            "France", "France_", "Italy", "Germany", "Spain" };

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

        ActionBar actionBar = getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setDisplayShowCustomEnabled(true);
        // actionBar.setDisplayShowTitleEnabled(false);
        // actionBar.setIcon(R.drawable.ic_action_search);

        LayoutInflater inflator = (LayoutInflater) this
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflator.inflate(R.layout.actionbar, null);

        actionBar.setCustomView(v);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_dropdown_item_1line, COUNTRIES);
        AutoCompleteTextView textView = (AutoCompleteTextView) v
                .findViewById(R.id.editText1);
        textView.setAdapter(adapter);

    }

}

和你的布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Action Bar:"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="#FFFFFF" />

    <AutoCompleteTextView
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:imeOptions="actionSearch"
        android:inputType="textAutoComplete|textAutoCorrect"
        android:textColor="#FFFFFF" >

        <requestFocus />
    </AutoCompleteTextView>

</LinearLayout>

编辑:

请检查这个和这个链接它可以帮助你。 代码在这里。

于 2013-04-08T11:09:53.637 回答
8

这是使用的替代方法CursorAdapter

ExampleActivity.java

private Menu menu;

@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.example, menu);

    this.menu = menu;

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

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

        SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();

        search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));

        search.setOnQueryTextListener(new OnQueryTextListener() { 

            @Override 
            public boolean onQueryTextChange(String query) {

                loadHistory(query);

                return true; 

            } 

        });

    }

    return true;

}

// History
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void loadHistory(String query) {

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

        Cursor cursor = db.rawQuery("SELECT * FROM items", null); // Example database query

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

        final SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();

        search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));

        search.setSuggestionsAdapter(new ExampleAdapter(this, cursor, items));

    }

}

现在您需要创建一个扩展自的适配器CursorAdapter

ExampleAdapter.java

public class ExampleAdapter extends CursorAdapter {

    private List<String> items;

    private TextView text;

    public ExampleAdapter(Context context, Cursor cursor, List<String> items) {

        super(context, cursor, false);

        this.items = items;

    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        text.setText(cursor.getString(cursor.getColumnIndex("text"))); // Example column index

    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View view = inflater.inflate(R.layout.item, parent, false);

        text = (TextView) view.findViewById(R.id.text);

        return view;

    }

}

请注意:导入时CursorAdapter不要导入Android支持版本,android.widget.CursorAdapter而是导入标准。

适配器还需要自定义布局:

资源/布局/item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView
        android:id="@+id/item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

您现在可以通过向布局添加额外的文本或图像视图并使用适配器中的数据填充它们来自定义列表项。现在你需要一个 SearchView 菜单项:

res/menu/example.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/search"
        android:title="@string/search"
        android:showAsAction="ifRoom"
        android:actionViewClass="android.widget.SearchView" />

</menu>

然后创建一个可搜索的配置:

res/xml/searchable.xml

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search"
    android:hint="@string/search" >
</searchable>

最后在清单文件的相关活动标签内添加:

AndroidManifest.xml

<intent-filter>
    <action android:name="android.intent.action.SEARCH" />
</intent-filter>

<meta-data
    android:name="android.app.default_searchable"
    android:value="com.example.ExampleActivity" />
<meta-data
    android:name="android.app.searchable"
    android:resource="@xml/searchable" />

请注意:@string/search示例中使用的字符串应在values/strings.xml中定义,也不要忘记更新com.example项目的引用。

这是原始教程供参考:

http://tpbapp.com/android-development/android-action-bar-searchview-tutorial

于 2014-03-16T03:35:10.763 回答
8

我也面临自动完成搜索视图的这个问题,并在不使用任何额外布局和自动完成文本视图的情况下修复它,有一个名为SearchAutoComplete的类。我用它来实现自动完成功能,只需放置一个简单的列表适配器,其中包含一个 ArrayList 项目建议与搜索视图。将适配器设置为您的SearchAutoComplete和自动完成功能将在下面是我的代码。请记住,您不必添加任何自定义布局。只需用我的代码替换您的 onCreateOptionsMenu(...) 方法:

    @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);

MenuItem searchItem = menu.findItem(R.id.search);
SearchView mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);

SearchAutoComplete searchAutoComplete = (SearchAutoComplete)     mSearchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, itemArrayList);
searchAutoComplete.setAdapter(adapter);

SearchManager searchManager =
(SearchManager) getSystemService(this.SEARCH_SERVICE);
mSearchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
return true;
}

单击建议的项目,该项目应出现在搜索视图中,因此在您将适配器设置为 searchAutoComplete 后在 onCreateOptionmenu(...) 方法中添加以下代码

  searchAutoComplete.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
    long id) {
    // TODO Auto-generated method stub

    String searchString=(String)parent.getItemAtPosition(position);
    searchAutoComplete.setText(""+searchString);
    Toast.makeText(MainActivity.this, "you clicked "+searchString, Toast.LENGTH_LONG).show();

    }
    });
于 2015-11-14T13:16:57.680 回答
6

是的,有可能。为您的建议构建一个表(例如在 SQLiteDatabase 中)并使用所需列格式化该表。

看到这个链接

于 2013-04-04T07:20:21.373 回答
1

您可以通过以下方式使用 CursorAdapter 执行此操作:

MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);

searchView.setSuggestionsAdapter(adapter);
于 2013-11-14T19:43:12.943 回答
1
    SearchAutoComplete searchAutoComplete = mSearchView.findViewById(androidx.appcompat.R.id.search_src_text);

适用于 androidx 版本

于 2019-05-10T12:22:32.997 回答