如何在 Action Bar Sherlock 中实现搜索小部件?

Posted

技术标签:

【中文标题】如何在 Action Bar Sherlock 中实现搜索小部件?【英文标题】:How to implement search widget in Action Bar Sherlock? 【发布时间】:2012-07-26 07:01:25 【问题描述】:

我试图让搜索框在 Action Bar Sherlock 上工作。

这是我的PreLocationActivity

    @ContentView(R.layout.search)
    public class PreLocationActivity extends RoboSherlockActivity 

        protected void onCreate(Bundle savedInstanceState) 
            super.onCreate(savedInstanceState);
            //setContentView(R.layout.map_layout);
         

        @Override
        public boolean onCreateOptionsMenu(Menu menu) 
            //Used to put dark icons on light action bar
             menu.add("Search")
             .setIcon(R.drawable.ic_search_inverse)
             .setActionView(R.layout.collapsible_edittext)
             .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
                return true;
        

        @Override
        public boolean onSearchRequested() 
            return super.onSearchRequested();
        
    

这是我的SearchableActivity

@ContentView(R.layout.search)
public class SearchableActivity extends RoboSherlockFragmentActivity 

    @InjectView(R.id.addressListView) ListView addressView;
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        // Get the intent, verify the action and get the query
        Intent intent = getIntent();
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) 
          String query = intent.getStringExtra(SearchManager.QUERY);
          doGeoSearch(query);
        


    public void doGeoSearch(String query)
        Geocoder geocoder;
        ArrayList<Address> addresses;
        ArrayList<String> address = new ArrayList<String>() ;
        geocoder = new Geocoder(this, Locale.getDefault());
        try 
            addresses = (ArrayList<Address>) geocoder.getFromLocationName(query, 6);
            Log.d("Address",String.valueOf(addresses));
            for(int i = 0;i<addresses.size();i++)
            
            String addr = new String();
            addr.concat(addresses.get(i).getAddressLine(0));
            addr.concat(addresses.get(i).getAddressLine(1));
            addr = addresses.get(i).getAddressLine(0) + addresses.get(i).getLocality() + addresses.get(i).getAdminArea();
            //addr.concat(addresses.get(i).getAddressLine(2));
            Log.d("addr",addr);
            address.add(addr);

            

            SearchAddressAdapater addressList = new SearchAddressAdapater(getApplicationContext(),R.layout.search_list,addresses, SearchableActivity.this);
            addressView.setAdapter(addressList);
            //ListView addressListView = new ListView();
         catch (IOException e) 
                //Handle exception
        
    

根本没有成功。例如,当我在 Prelocation Activity 上键入内容并按 Enter 键时,没有搜索任何内容。我是否必须将其视为EditText 并为其编写一个文本侦听器,然后调用geoCoder 并为我获取位置,或者是否有更聪明的方法来解决它?

【问题讨论】:

在这里你可以查看我对类似问题的回答:***.com/a/21972031/2220495 【参考方案1】:

android 支持库(v4 + v7):

支持库 v7: http://developer.android.com/tools/support-library/features.html#v7-appcompat

Google 现在支持将 ActionBar 兼容性回溯到 Android 2.1(API 7)。

转换很容易,因为方法名称相同和/或非常相似。

使用资源添加支持库: http://developer.android.com/tools/support-library/setup.html#libs-with-res

您的清单:AndroidManifest.xml

<uses-sdk
  android:minSdkVersion="7"
  android:targetSdkVersion="17" />

您的菜单:menu.xml

<item
    android:id="@+id/menu_search"
    android:actionViewClass="android.support.v7.widget.SearchView"
    android:icon="@drawable/ic_action_search"
    android:showAsAction="ifRoom|collapseActionView"
    android:title="Search"/>

ActionBarSherlock [已弃用,使用 appcompat]:

这里是如何在 Android 中使用标准的 SearchView 和 SearchManager 与 ActionBarSherlock!我正在使用此代码并且工作正常。我已经在 Android 2.3(API 10) - Android 4.3(API 18) 上对此进行了测试。

很棒的教程和文档:

http://developer.samsung.com/android/technical-docs/UI-unification-with-older-Android-versions-using-ActionBarSherlock

记住:

使用 ActionBarSherlock 进行自定义搜索(最低 API 7)

带有 ActionBarSherlock 的 SearchView(最低 API 8)

您的菜单:menu.xml

<item
    android:id="@+id/menu_search"
    android:actionViewClass="com.actionbarsherlock.widget.SearchView"
    android:icon="@drawable/ic_action_search"
    android:showAsAction="ifRoom|collapseActionView"
    android:title="Search"/>

对于两者:

您的活动:MainActivity.java

public boolean onCreateOptionsMenu(Menu menu) 

        getSupportMenuInflater().inflate(R.menu.menu, menu);

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
        if (null != searchView )
        
            searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
            searchView.setIconifiedByDefault(false);   
        

        SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() 
        
            public boolean onQueryTextChange(String newText) 
            
                // this is your adapter that will be filtered
                adapter.getFilter().filter(newText);
                return true;
            

            public boolean onQueryTextSubmit(String query) 
            
                // this is your adapter that will be filtered
                adapter.getFilter().filter(query);
                return true;
            
        ;
        searchView.setOnQueryTextListener(queryTextListener);
        
        return super.onCreateOptionsMenu(menu);
    

让我知道这是否也适合您,如果您需要更多帮助,请告诉我!

【讨论】:

适配器是您的 ListView 适配器。将数据绑定到视图。 好的...谢谢。还有一件事要问,如果我需要在 ActionBar 上再包含一个 menuItem 怎么办,比如说一个按钮。通常,对于多个项目,我们使用 Switch case,但在这里我有点困惑,我们如何在操作栏上再创建一个项目。 在包含 android:actionViewClass="com.actionbarsherlock.widget.SearchView" 后显示 classcasteception 。 我下载了 ABS 4.4,将其解压缩,转到 Eclipse 并从源代码创建了 android 项目并选择了 actionbarsherlock,通过引用您的答案创建了一个新项目,但我收到错误找不到类 'com. actionbarsherlock.widget.SuggestionsAdapter'。我还将此作为堆栈溢出问题发布***.com/q/20835518/992665 @Sar009 根据库的不同,您还需要确保使用正确的主题。【参考方案2】:
private EditText search;

public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu)

    menu.add(0, 1, 1, R.string.menu_search).setIcon(R.drawable.ic_action_search).setActionView(R.layout.action_search).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
    return super.onCreateOptionsMenu(menu);


@Override
public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item)

    switch (item.getItemId())
    
        case 1:
        search = (EditText) item.getActionView();
        search.addTextChangedListener(filterTextWatcher);
        search.requestFocus();
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
    


private TextWatcher filterTextWatcher = new TextWatcher()

    public void afterTextChanged(Editable s)
    
    

    public void beforeTextChanged(CharSequence s, int start, int count, int after)
    
    

    public void onTextChanged(CharSequence s, int start, int before, int count)
    
        // your search logic here
    
;

【讨论】:

我试过这个。这有效,但与 Searchable 活动不完全一样。历史记录未保存。 Georgy,我刚刚尝试了您的解决方案,但我的 EditText 没有调用 TextWatcher 的方法。有什么建议吗? 您是否将 TextChangedListener 设置为 EditText? 出于某种原因,我遇到了很大的问题。请查看:wptrafficanalyzer.in/blog/….【参考方案3】:

这里有一个类似的问题,我在分配适配器时遇到了问题。

How to implement search widget with a listview using SherlockActionbar?

我希望它会有所帮助,因为我遇到了同样的问题。

要使用适配器,最好的方法是类实现 SearchView.OnQueryTextListener,然后您不必创建内部类,您将拥有适配器。

在您的代码中将是:

public class MainActivity extends SherlockListActivity implements SearchView.OnQueryTextListener

然后你必须在类中定义方法。适配器将是您在类 ArrayAdapter 适配器中拥有的适配器。但是你应该在类中将它定义为私有的。

public boolean onQueryTextChange(String newText) 
    // this is your adapter that will be filtered
    adapter.getFilter().filter(newText);
    return true;


public boolean onQueryTextSubmit(String query) 
    // this is your adapter that will be filtered
    adapter.getFilter().filter(query);
    return true;

在您设置的行中:

 searchView.setOnQueryTextListener(queryTextListener);

应该是:

 searchView.setOnQueryTextListener(this);

如果您有任何问题,请告诉我,我今天遇到了类似的问题,并且没有回答就阅读了您的问题。

【讨论】:

以上是关于如何在 Action Bar Sherlock 中实现搜索小部件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中找到系统Action Bar中存在的不同图标的宽度

如何使用Angular2在Telerik的Nativescript UI中的Action Bar上显示sideDrawer?

Sherlock 操作栏更改文本颜色

Android中Action Bar的使用

如何将覆盖视图放在操作栏上 Sherlock

Android: Action Bar的使用