How to use Android SearchView without singleTop?

I have an activity that I usually want to exist in several tasks, so the [Back] button restores the previous state; however, I also want to use SearchView with an existing action without pushing a new one onto the task stack (since I want to search for what is currently displayed). Here is my problem:

  • If I set the activity start mode to "singleTop", SearchView will work with the current action, but Context.startActivity does not add new actions to the stack.
  • If I set the activity start mode to “standard”, startActivity adds new actions to the stack, but SearchView also creates a new (empty) activity instead of searching for an existing one.

I can’t find any way to make the flags of intent using SearchView (for example, FLAG_ACTIVITY_SINGLE_TOP . I tried the other way around by setting the mode to "singleTop" and then add FLAG_ACTIVITY_NEW_TASK to any intentions, but it only worked when I started from another activity class when I I try to start a new instance of activity from my own class, Android did not respect FLAG_ACTIVITY_NEW_TASK and did not push a new task onto the stack.

Perhaps there is something that I can do in Activity.onNewIntent to make it clone.

I’m on the verge of abandoning SearchView and just creating my own widget, despite the fact that “Starting with Android 3.0 using the SearchView widget as an element in the action bar is the preferred way to provide a search in your application” ( Source ) - still it seems too inflexible and not customizable to be useful in non-trivial cases.

Has anyone found a solution to this problem?

+5
source share
2 answers

After much thought and false starts, I realized that SearchView was simply wrong for this task. Google developed SearchView with a very specific type of search activity:

  • The user enters into a search query.
  • , .

, ; , , - , . SearchView , ( ).

, - Android . , .

+4

, OP, , SearchView. , , , .

OP...

, Android FLAG_ACTIVITY_NEW_TASK

... , . DummyActivity, .

, ...

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

... ...

/*
 * 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);

DesinationActivity singleTop.

, , DummyActivity, - ...

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

}

, . . .

+1

All Articles