2010-10-25 59 views
11

有谁知道如何动态设置android搜索对话框提示? T的尝试做这样的事情:动态设置搜索提示

<?xml version="1.0" encoding="utf-8"?> 
<searchable xmlns:android="http://schemas.android.com/apk/res/android" 
android:label="@string/search_label" 
android:hint="@string/search_hint" 
android:id="@+id/search_dialog_text"> 
</searchable> 

某处:

@Override 
public boolean onSearchRequested() { 
    Bundle appSearchData = new Bundle(); 
    appSearchData.putString("SomeSpecificParam", SomeClass.class.getName()); 
    startSearch("", false, appSearchData, false); 
    EditText text = (EditText)findViewById(R.id.search_dialog_text); 
    text.setHint("Search something else"); 
    return true; 
} 

但文本等于空。

所以期待你的建议。谢谢。

回答

5

这种感觉相当哈克,但对我的工作 - 而不是真正的动态,但工作了我所需要的两个搜索提示之间交替:

  1. 我创建了一个第二searchable.xml(如Android search docs描述的),叫searchable2.xml,并定义了我的第二个搜索提示。
  2. 我创建了一个从我原来的活动延伸出来的虚拟活动,并且不重写任何东西。
  3. 在清单中的虚设活性与新searchable2.xml相关联:

    <activity android:name=".MainActivity"> 
        <intent-filter> 
         <action android:name="android.intent.action.VIEW" /> 
         <action android:name="android.intent.action.SEARCH" /> 
        </intent-filter> 
        <meta-data android:name="android.app.searchable" 
         android:resource="@xml/searchable"/> 
    </activity> 
    
    <activity android:name=".DummyActivity"> 
        <intent-filter> 
         <action android:name="android.intent.action.VIEW" /> 
         <action android:name="android.intent.action.SEARCH" /> 
        </intent-filter> 
        <meta-data android:name="android.app.searchable" 
         android:resource="@xml/searchable2"/> 
    </activity> 
    
  4. 在 'MainActivity' 我推翻 'onSearchRequested()' 来引用相应的搜索活动:

    
    public boolean onSearchRequested() 
    { 
         SearchManager searchManager = (SearchManager)getSystemService(Context.SEARCH_SERVICE);
    if(searchManager!=null) { // start the search with the appropriate searchable activity // so we get the correct search hint in the search dialog if(/* your condition here */) searchManager.startSearch(null, false,new ComponentName(this, MainActivity.class), null, false); else searchManager.startSearch(null, false,new ComponentName(this, DummyActivity.class), null, false);

    return true; } return false; }

令人讨厌。但绝望的时代呼吁采取绝望的措施......

AFAIK,从查看Android源,该类只用于查找元数据,但如果有人知道不同,那么请让我知道。

+0

非常有趣的黑客。凌乱,但似乎有效。你能想出一种方法来允许这种动态发生吗?即在运行时更新搜索提示?例如格式化一个提示字符串,其中包含正在搜索的项目的数量 – ohhorob 2010-12-14 20:06:18

2

他们已经增加了一个注释,指出

注:系统使用此文件来实例化一个SearchableInfo对象,但是你不能在运行时自己创建这个对象 - 你必须声明XML中的可搜索配置。

所以看起来你的问题的答案是你不能动态设置搜索对话框提示。

2

我管理与使用OnActionExpandListener和一个自定义的actionView ABS做到这一点,例如:

menu.add("Search") 
.setActionView(R.layout.collapsible_edittext) 
.setOnActionExpandListener(new MenuItem.OnActionExpandListener() 
{ 
    @Override 
    public boolean onMenuItemActionExpand(MenuItem item) { 
     ((EditText) item.getActionView()).setHint("Your custom text here"); 
     return true; 
    } 

    @Override 
    public boolean onMenuItemActionCollapse(MenuItem item) { 
     return true; 
    } 
}); 

与collapsible_edittext。XML:

<EditText 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:textColor="@color/search_fg" 
    android:background="@drawable/textfield_default_holo_light" 
    android:hint="[will be replaced at runtime]"/> 
0

感谢村上先生的想法,我已经实现了相同的概念来进行切换搜索和按我的看法,它不是一个技巧,但其糟糕的美。下面的程序在操作栏中具有切换图标以在搜索提示之间切换。

  1. RestaurantListingActivity.java

    public class RestaurantListingActivity extends BaseMainActivity implements 
    TabListener { 
    private boolean isRestaurantSearch = true; 
    private SearchManager searchManager; 
    private SearchView searchView; 
    
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        ActionBar aBar = getActionBar(); 
        aBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
        aBar.addTab(aBar.newTab().setText("Place Order").setTabListener(this)); 
        aBar.addTab(aBar.newTab().setText("My Account").setTabListener(this)); 
        aBar.addTab(aBar.newTab().setText("Favorite").setTabListener(this)); 
        aBar.addTab(aBar.newTab().setText("Vendor Portal").setTabListener(this)); 
    } 
    
    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
        getMenuInflater().inflate(R.menu.restaturant_listing_menu, menu); 
        searchManager = (SearchManager) getSystemService(SEARCH_SERVICE); 
        searchView = (SearchView) menu.findItem(R.id.rlm_search) 
          .getActionView(); 
        searchView.setSearchableInfo(searchManager 
          .getSearchableInfo(new ComponentName(this, 
            RestaurantListingActivity.class))); 
        return super.onCreateOptionsMenu(menu); 
    } 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
        switch (item.getItemId()) { 
        case R.id.rlm_toggle: 
    isRestaurantSearch = !isRestaurantSearch; 
        if (isRestaurantSearch) 
         searchView.setSearchableInfo(searchManager 
           .getSearchableInfo(new ComponentName(this, 
             RestaurantListingActivity.class))); 
        else 
         searchView.setSearchableInfo(searchManager 
           .getSearchableInfo(new ComponentName(this, 
             RestaurantFoodSwitcherActivity.class))); 
    
    
        break; 
    case R.id.rlm_change_loc: 
    
        break; 
    case R.id.rlm_filter_search: 
    
        break; 
    } 
    
        return super.onOptionsItemSelected(item); 
    } 
    
    @Override 
    public void onTabReselected(Tab tab, FragmentTransaction ft) { 
        // TODO Auto-generated method stub 
    
    } 
    
    @Override 
    public void onTabSelected(Tab tab, FragmentTransaction ft) { 
    // TODO Auto-generated method stub 
    } 
    
    @Override 
    public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
        // TODO Auto-generated method stub 
    
    } 
    
    @Override 
    public void setScreenData(Object screenData, int event, long time) { 
        // TODO Auto-generated method stub 
    
    } 
    
    @Override 
    public Activity getMyActivityReference() { 
        // TODO Auto-generated method stub 
        return null; 
    } 
    
    @Override 
    public void onClick(View v) { 
        // TODO Auto-generated method stub 
    
    } 
    } 
    
  2. restaurant_listing_menu

<item 
    android:id="@+id/rlm_toggle" 
    android:showAsAction="always" 
    android:title="Toggle Search" 
    android:icon="@drawable/ic_action_refresh" 
    > 
</item> 
<item 
    android:id="@+id/rlm_search" 
    android:showAsAction="always|collapseActionView" 
    android:title="Search" 
    android:icon="@drawable/ic_action_search" 
    android:actionViewClass="android.widget.SearchView" 
    > 
</item> 
<item 
    android:id="@+id/rlm_filter_search" 
    android:showAsAction="ifRoom" 
    android:title="Filter Search" 
    android:icon="@drawable/ic_action_settings" 
    > 
</item> 
<item 
    android:id="@+id/rlm_change_loc" 
    android:showAsAction="ifRoom" 
    android:title="Change Location" 
    android:icon="@drawable/ic_action_location_off" 
    > 
</item> 

  1. searchablerestra.xml内部RES> XML

    <?xml version="1.0" encoding="utf-8"?> 
    <searchable xmlns:android="http://schemas.android.com/apk/res/android" 
    android:hint="@string/search_hint_restra" 
    android:label="@string/app_name"> 
    </searchable> 
    
  2. RestaurantFoodSwitcherActivity.java

    public class RestaurantFoodSwitcherActivity extends RestaurantListingActivity { 
    } 
    
  3. searchablefood.xml

    <?xml version="1.0" encoding="utf-8"?> 
    <searchable xmlns:android="http://schemas.android.com/apk/res/android" 
        android:hint="@string/search_hint_food" 
        android:label="@string/app_name"> 
    </searchable> 
    
  4. 的manifest.xml

    <activity   android:name="com.example.app.ui.activity.RestaurantListingActivity" > 
        <!-- This intent-filter identifies this activity as "searchable" --> 
        <intent-filter> 
         <action android:name="android.intent.action.SEARCH" /> 
    
         <category android:name="android.intent.category.DEFAULT" /> 
        </intent-filter> 
        <!-- This metadata entry provides further configuration details for searches --> 
        <!-- that are handled by this activity. --> 
        <meta-data 
         android:name="android.app.searchable" 
         android:resource="@xml/searchablerestra" 
    
         /> 
    </activity> 
    <activity android:name="com.example.app.ui.activity.RestaurantFoodSwitcherActivity"> 
        <!-- This intent-filter identifies this activity as "searchable" --> 
        <intent-filter> 
         <action android:name="android.intent.action.SEARCH" /> 
    
         <category android:name="android.intent.category.DEFAULT" /> 
        </intent-filter> 
        <!-- This metadata entry provides further configuration details for searches --> 
        <!-- that are handled by this activity. --> 
        <meta-data 
         android:name="android.app.searchable" 
         android:resource="@xml/searchablefood" 
         /> 
    </activity> 
    
1

有一个比上述任何一个更简单的答案。它加载默认searchable.xml为您的活动,然后使用Java反射来更新SearchableInfo实例内的私人mHintId领域:

@Override 
public void onPrepareOptionsMenu(Menu menu) { 
    SearchManager searchManager = (SearchManager)getActivity().getSystemService(Context.SEARCH_SERVICE); 
    SearchableInfo si = searchManager.getSearchableInfo(getActivity().getComponentName()); 

    try { 
     Field mHintId = si.getClass().getDeclaredField("mHintId"); 
     mHintId.setAccessible(true); 
     mHintId.setInt(si, R.string.your_custom_hint); 
    } catch (Exception e) { 
    } 

    MenuItem mi = menu.findItem(R.id.menu_search); 
    SearchView searchView = (SearchView)mi.getActionView(); 
    searchView.setSearchableInfo(si); 
} 
+0

以上是最好的,最简单的方法。忘掉所有其他复杂的建议! – 2014-05-12 05:49:05

+0

@zyamys从哪个类和什么方法调用invalidateLayout(),以便这个onPrepareOptionsMenu()覆盖被调用?谢谢! – Rachael 2016-07-25 21:27:10

+0

它被框架调用,你不需要调用Activity。 invalidateOptionsMenu()除非需要出于某种不相关的原因。 – zyamys 2016-07-25 21:31:30

2

如果您使用的是ToolbarSearchView小工具,你可以轻松地设置搜索通过调用查询提示:

SearchView.setQueryHint(CharSequence hint)