2010-10-25 2 views
11

Qualcuno sa come impostare dinamicamente la finestra di dialogo di ricerca di Android? T hanno provare a fare qualcosa di simile:Imposta dinamicamente l'hint di ricerca

<?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> 

Da qualche parte:

@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; 
} 

ma il testo è uguale nullo.

Quindi in attesa di suggerimenti. Grazie.

risposta

5

questo si sente abbastanza hacky, ma ha lavorato per me - non è veramente dinamico, ma ha lavorato per alternanza tra i due suggerimenti di ricerca di cui avevo bisogno:

  1. ho creato un secondo searchable.xml (come descritto nella Android search docs), chiamato searchable2.xml, con il mio secondo hint di ricerca definito.
  2. Ho creato un'attività fittizia estesa dalla mia attività originale e ignorando nulla.
  3. sul manifesto le attività di manichino è stato associato con la nuova 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. In 'MainActivity' Io overrode 'onSearchRequested()' per fare riferimento all'attività ricercabile appropriata:

    
    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; }

Nasty. Ma i tempi disperati richiedono misure disperate ...

AFAIK, e guardando la sorgente di Android la classe è usata solo per cercare i metadati, ma se qualcuno sa diversamente, per favore fatemelo sapere.

+0

Hack molto interessante. Disordinato, ma sembra efficace. Riesci a pensare a un modo per permettere che questo accada in modo dinamico? Ad esempio, aggiorna l'hint di ricerca al runtime? per esempio. formattare una stringa di suggerimento con un conteggio in tempo reale del numero di elementi ricercati – ohhorob

1

Sembra che tu sia quasi arrivato.

L'origine SearchDialog fa in modo che l'auto sia completamente modificabile.

mSearchAutoComplete = (SearchAutoComplete) findViewById(com.android.internal.R.id.search_src_text); 

(notare che la classe SearchAutoComplete è una sottoclasse di AutoCompleteTextView)

2

Hanno aggiunto una nota a http://developer.android.com/guide/topics/search/search-dialog.html#SearchableConfiguration affermando che

Nota: Il sistema utilizza questo file di istanziare un oggetto SearchableInfo, ma non è possibile creare questo oggetto da soli durante il runtime; è necessario dichiarare la configurazione ricercabile in XML.

Quindi sembra che la risposta alla tua domanda è che non è possibile impostare dinamicamente il suggerimento della finestra di ricerca.

2

sono riuscito a fare questo con ABS con l'OnActionExpandListener e ActionView personalizzato, ad es .:

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; 
    } 
}); 

con 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

Grazie signor Murakami per l'idea, ho implementato lo stesso concetto per effettuare la ricerca di commutazione e secondo me non è un trucco, ma la sua bellezza di OOPs. Sotto il programma con un'icona di commutazione nella barra delle azioni per passare da suggerimento di ricerca.

  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 all'interno> 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

C'è una risposta molto più semplice di una qualsiasi delle precedenti. Si carica la searchable.xml di default per la vostra attività, e quindi utilizza java riflessione per aggiornare il campo privato mHintId all'interno dell'istanza SearchableInfo:

@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

Quanto sopra è il metodo migliore e più semplice. Dimentica tutti gli altri suggerimenti complessi! –

+0

@zyamys da quale classe e quale metodo stai chiamando invalidateLayout() in modo che venga chiamata questa sovrascrittura onPrepareOptionsMenu()? Grazie! – Rachael

+0

Viene chiamato dal framework, non è necessario chiamare Activity. invalidateOptionsMenu() a meno che non sia necessario per qualche motivo non correlato. – zyamys

2

Se si utilizzano i Toolbar e SearchView widget, si può facilmente impostare la ricerca suggerimento per le query chiamando:

SearchView.setQueryHint(CharSequence hint)