2013-02-09 23 views
5

Ho un'attività che normalmente desidero esistere in più attività, in modo che il pulsante [Indietro] ripristini uno stato precedente; tuttavia, voglio anche usare uno SearchView con un'attività esistente, senza spingerne uno nuovo nello stack delle attività (poiché voglio cercare ciò che è attualmente visualizzato). Ecco il mio problema:Come utilizzare un SearchView Android senza singleTop?

  • Se ho impostato la modalità di lancio della propria attività a "singleTop", il SearchView lavora con l'attività corrente, ma Context.startActivity non aggiunge nuove attività per lo stack.
  • Se imposto la modalità di avvio dell'attività su "standard", startActivity aggiunge nuove attività allo stack, ma SearchView crea anche una nuova attività (vuota), anziché cercare quella esistente.

non riesco a trovare alcun modo rendere SearchView utilizzare bandiere intenti (ad es FLAG_ACTIVITY_SINGLE_TOP. Ho provato ad andare il contrario, impostando la modalità di lancio per "singleTop" aggiungendo poi FLAG_ACTIVITY_NEW_TASK ad ogni intenzione, ma che funzionava solo al momento del lancio da una diversa classe di attività, quando provo a lanciare una nuova istanza di un'attività dalla propria classe, Android non ha rispettato FLAG_ACTIVITY_NEW_TASK e non ha spinto una nuova attività nello stack

Forse c'è qualcosa che posso fare. in Activity.onNewIntent per forzare quindi l'attività a clonare se stesso.

Sono sull'orlo di givin g su SearchView e basta scrivere il mio widget personalizzato, nonostante il fatto che "A partire da Android 3.0, utilizzando il widget SearchView come elemento nella barra delle azioni è il modo preferito per fornire la ricerca nella tua app" (Source) - finora, sembra troppo poco flessibile e non configurabile per essere utile in casi non banali.

Qualcuno ha trovato una soluzione a questo problema?

+0

Dalla mancanza totale di risposte (e basso numero di visualizzazioni), suppongo che questo sia un problema non banale. Esiste un altro possibile aggiramento (oltre a evitare semplicemente SearchView): potrei progettare l'attività SingleTop per mantenere il proprio stato di stato e cambiare stato, quindi intercettare il pulsante Indietro per simulare lo spostamento attraverso lo stack delle attività. Ho una forte avversione, tuttavia, a sostituire le funzionalità del sistema operativo principale con le simulazioni: se questa è l'unica opzione, deciderò semplicemente che Google ha consigliato SearchView prematuramente per l'uso di produzione e creerà il mio componente di azione di ricerca. – Canuck

risposta

4

Dopo molte riflessioni e false partenze, mi sono reso conto che SearchView era semplicemente la cosa sbagliata per questo compito. Google ha progettato SearchView con un tipo molto specifico di attività di ricerca in mente:

  • L'utente digita una query di ricerca.
  • L'app invia una nuova attività che mostra un elenco di risultati.

Questo non è il modello di ricerca che stavo usando; invece, volevo perfezionare un elenco attualmente visualizzato sullo schermo utilizzando la query: si trattava più di una ricerca di filtro che di una query sincrona e un modello di risposta. SearchView non è progettato per questo, quindi sono andato avanti e ho scritto il mio widget personale (e lo ho associato alla voce del menu di ricerca e al pulsante di ricerca).

Sono sorpreso del fatto che nessuno abbia avuto commenti su questa domanda: in genere le domande su Android generano molte discussioni. Immagino che questo fosse troppo esagerato.

+1

Mi chiedevo se posso usare SearchView per filtrare anche gli elementi già visibili! Grazie per aver sottolineato che SearchView intende avviare un'altra azione! Avevo esattamente la stessa domanda in mente. –

+0

Grazie per il commento, Lars - Stavo iniziando a pensare di essere l'unico. – Canuck

1

Ho avuto lo stesso problema dell'OP, ma ho una soluzione che non significa rinunciare all'uso di SearchView. Non è la soluzione perfetta, ma è abbastanza pulito e sembra funzionare bene.

Come indicato dall'OP ...

quando provo a lanciare una nuova istanza di un'attività dalla propria classe, Android non ha rispettato FLAG_ACTIVITY_NEW_TASK e non ha spinto una nuova attività nello stack

... quindi il mio la soluzione è passare per un'attività intermedia. Per questo, ho creato una classe DummyActivity che fondamentalmente riprende l'intento originale e la inoltra all'attività di destinazione.

Così, dalla mia attività originaria, invece di chiamare ...

Intent destinationIntent = new Intent(getActivity(), DestinationActivity.class); 
startActivity(destinationIntent); 

... io chiamo ...

/* 
* Create the intent as normal, but replace our destination Activity with DummyActivity 
*/ 
Intent dummyIntent = new Intent(getActivity(), DummyActivity.class); 

/* 
* This will make it so that if user clicks back from the next activity, they won't be shown DummyActivity 
*/ 
dummyIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 

/* 
* Tell DummyActivity about the destination Activity 
*/ 
dummyIntent.putExtra(DummyActivity.EXTRA_DESTINATION_ACTIVITY, YourDestinationActivity.class); //IMPORTANT - the destination Activity must implement Serializable 

/* 
* If you want, you can add any other extras to dummyIntent (which will be passed through to the destination activity). Launch DummyActivity. 
*/ 
startActivity(dummyIntent); 

Nel mio manifesto, DesinationActivity è definito come singleTop.

E l'unica altra cosa che dovrebbe essere necessario è la classe DummyActivity che non dovrebbe avere bisogno di qualsiasi grande personalizzazione ...

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 

public class DummyActivity extends Activity { 

    public static final String EXTRA_DESTINATION_ACTIVITY = "uk.co.mobilewebexpert.EXTRA_DESTINATION_ACTIVITY"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     //setContentView(R.layout.activity_dummy); 

     Intent intent = getIntent(); 

     /* 
     * Get destination activity info 
     */ 
     @SuppressWarnings("unchecked") 
     Class<Activity> destinationActivity = (Class<Activity>) intent.getSerializableExtra(EXTRA_DESTINATION_ACTIVITY); 
     Bundle destinationActivityExtras = intent.getExtras(); 

     /* 
     * Launch destination activity 
     */ 
     Intent destinationActivityIntent = new Intent(this, destinationActivity); 
     destinationActivityIntent.putExtras(destinationActivityExtras); 
     destinationActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     startActivity(destinationActivityIntent); 
    } 

    /** 
    * Override super.onNewIntent() so that calls to getIntent() will return the latest 
    * intent, rather than the first intent. 
    */ 
    @Override 
    public void onNewIntent(Intent intent){ 
     super.onNewIntent(intent); 
     setIntent(intent); 
    } 

} 

Speriamo che questo funzionerà anche per te. Suggerimenti accolti Saluti.

Problemi correlati