2010-10-25 58 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)