2013-10-11 51 views
10

Ich versuche, meine App zu einer EINZIGEN Aktivität zu machen. Diese Aktivität sollte in der Lage sein, eine Suche zu erstellen und auch eine Suche zu erhalten. Leider bekomme ich in meinem SearchView eine "doppelte" Suchleiste, wenn ich auf den Suchknopf in der Aktionsleiste klicke. Ich meine, dass es eine Suchleiste (dark - SearchView) gibt, die für eine Sekunde in der Aktionsleiste erscheint und dann eine zweite (weiß) über der Aktionsleiste erscheint. Irgendeine Hilfe? Was mache ich falsch? Entschuldigung, diese Suche ist alles neu und verwirrend für mich.Android-Suchaktivität in Einzelaktivität

MainActivity (die einzige Aktivität):

public class MainActivity extends ActionBarActivity { 
Menu mMenu; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    //getSupportActionBar().setDisplayShowTitleEnabled(false); 
    setContentView(R.layout.activity_main); 

    handleIntent(getIntent()); 
} 

@Override 
protected void onNewIntent(Intent intent) { 
    handleIntent(intent); 
} 

private void handleIntent(Intent intent) { 
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) { 
     String query = intent.getStringExtra(SearchManager.QUERY); 
     //use the query to search your data somehow 
    } 
} 

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



    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
     SearchManager searchManager = 
       (SearchManager) getSystemService(Context.SEARCH_SERVICE); 
     SearchView searchView = 
       (SearchView) menu.findItem(R.id.search).getActionView(); 
     searchView.setSearchableInfo(
       searchManager.getSearchableInfo(getComponentName())); 
     searchView.setIconifiedByDefault(false); 
    } 


    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case R.id.search: 
      onSearchRequested(); 
      return true; 
     default: 
      return false; 
    } 
} 

@SuppressLint("NewApi") 
@Override 
public boolean onSearchRequested() { 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 
     MenuItem mi = mMenu.findItem(R.id.search); 
     if(mi.isActionViewExpanded()){ 
      mi.collapseActionView(); 
     } else{ 
      mi.expandActionView(); 
     } 
    } else{ 
     //onOptionsItemSelected(mMenu.findItem(R.id.search)); 
    } 
    return super.onSearchRequested(); 
} 
} 

main.xml (das Menü xml):

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

<item android:id="@+id/search" 
     android:title="@string/action_settings" 
     android:icon="@drawable/ic_launcher" 
     android:actionProviderClass="android.support.v7.widget.ShareActionProvider" 
     com.brianco.andypedia:showAsAction="always|collapseActionView" 
     com.brianco.andypedia:actionViewClass="android.support.v7.widget.SearchView" /> 

<item 
    android:id="@+id/action_settings" 
    android:orderInCategory="100" 
    android:showAsAction="never" 
    android:title="@string/action_settings"/> 

</menu> 

searchable.xml:

<?xml version="1.0" encoding="utf-8"?> 
<searchable xmlns:android="http://schemas.android.com/apk/res/android" 
    android:label="@string/app_name" 
    android:hint="@string/search_hint" 
    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" /> 

im manifesten:

<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/Theme.AppCompat.Light.DarkActionBar" > 
    <activity 
     android:name="com.brianco.andypedia.MainActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
     <intent-filter> 
      <action android:name="android.intent.action.SEARCH" /> 
     </intent-filter> 
     <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> 
    </activity> 

    <meta-data android:name="android.app.default_searchable" 
     android:value=".MainActivity" /> 

Antwort

2

Okay, das Problem hatte mit dem Aufruf von onSearchRequested() in onOptionsItemSelected (MenuItem Element) zu tun. Das ist redundant, wenn ich ein SearchView habe und nur auf älteren Plattformen aufgerufen werden sollte.

Also habe ich einen separaten Menüpunkt für Geräte unter Honeycomb erstellt. Es wird zur Laufzeit für neuere Geräte entfernt. Das SearchView wird zur Laufzeit für ältere Geräte entfernt.

Siehe aktualisierte Code unten:

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



    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
     //remove old 
     menu.removeItem(R.id.search_old); 
     SearchManager searchManager = 
       (SearchManager) getSystemService(Context.SEARCH_SERVICE); 
     SearchView searchView = 
       (SearchView) menu.findItem(R.id.search).getActionView(); 
     searchView.setSearchableInfo(
       searchManager.getSearchableInfo(getComponentName())); 
     searchView.setIconifiedByDefault(false); 
    } else{ 
     //remove new 
     menu.removeItem(R.id.search); 
    } 


    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case R.id.search_old: 
      onSearchRequested(); 
      return true; 
     default: 
      return false; 
    } 
} 

@SuppressLint("NewApi") 
@Override 
public boolean onSearchRequested() { 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 
     MenuItem mi = mMenu.findItem(R.id.search); 
     if(mi.isActionViewExpanded()){ 
      mi.collapseActionView(); 
     } else{ 
      mi.expandActionView(); 
     } 
    } else{ 
     //onOptionsItemSelected(mMenu.findItem(R.id.search)); 
    } 
    return super.onSearchRequested(); 
} 
11

Bitte versuchen Sie das folgende Attribut zu Ihrem <activity> in Ihrer Manifest-Datei hinzufügen:

android:launchMode="singleTop" 

Dies wird die gleiche Tätigkeit, um die Suchabsicht zu erhalten.

Mehr Infos hier: http://developer.android.com/guide/topics/manifest/activity-element.html

Außerdem haben Sie <intent-filter> zweimal erklärt, sollten Sie es in ein Element verschmelzen.

+0

Danke, ich habe mein Manifest aktualisiert. Das war nicht mein Problem, aber es ist wirklich gut zu wissen. Sehen Sie meine Antwort für meine Lösung für das Problem, das ich hatte. –

+0

Großartig, gut zu wissen für mich auch! – Szymon

+1

Denken Sie daran, die onNewIntent() -Methode zu verwenden, um Ihre Suchanfrage zu bearbeiten, wie von Phil erklärt. – djondal

21

Von Setting Up the Search Interface im Android Dokumentation:

In Ihrer durchsuchbar Tätigkeit übernimmt die ACTION_SEARCH Absicht von für sie in Ihrem onCreate() Methode zu überprüfen.

Hinweis: Wenn Ihr durchsuchbaren Aktivitäts startet in einzelnen Top-Modus (android: launchMode = "singleTop") behandeln auch die ACTION_SEARCH Absicht im onNewIntent() -Methode. Im Single-Top-Modus wird nur eine Instanz von Ihre Aktivität erstellt und nachfolgende Aufrufe zum Starten Ihrer Aktivität erstellen keine neue Aktivität auf dem Stapel. Dieser Startmodus ist nützlich , damit Benutzer Suchvorgänge aus derselben Aktivität durchführen können, ohne jedes Mal eine neue Aktivitätsinstanz zu erstellen.