Changing fragment from SearchView submit aka Cascading down the backstack
I'm currently using a SearchView
object in order to give my application functionality for suggested input.
This widget however, when submitted, uses an intent-filter
to to initiate your searching. This is great when my application is run on a phone because what I want to do is launch a Search Results Activity
to display the response. However on a tablet I want it to load my search results in a Fragment located in the current Activity
!
I want my app to be as unified as possible (In terms of crossover between phone/tab) so instead of overwriting the submit behaviour as suggested in this answer I would like a new activity to be started which routes the search term w开发者_如何学运维here it needs to go. On a phone to the results Activity, on a tab I would like to pass the searchTerm to the previous Activity.
So I would like to ask - Can you pass information to a previous Activity in the backstack?
I would suggest you having your SearchCatchingActivity acting as a routing Activity. It can catch query and pass it to the required Activity (be it dual pane with result fragment or a single pane with single result fragment). Use FLAG_ACTIVITY_CLEAR_TOP
intent flag when routing to the next Activity so that it becomes the default Activity of that instance. Remember to call finish()
on your routing activity to remove it from the backstack as well.
I just set the launch mode of my activity to singleTop and handle the onNewIntent method for this.
AndroidManifest.xml
<activity android:name=".MyActivity" android:launchMode="singleTop" android:theme="@style/Theme.MyTheme" >
<intent-filter >
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
MyActivity.java (This is obviously over-simplified - you could just have a public method on your existing fragment to pass it the search query. In the example below I replace it with a brand new fragment.)
@Override
protected void onNewIntent (Intent intent) {
MyFragment newFrag = new MyFragment();
newFrag.setArguments(args);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
// remove previous show list fragment if it exists
Fragment prev = getSupportFragmentManager().findFragmentByTag("myFrag");
if (prev != null) {
ft.remove(prev);
}
ft.add(R.id.fragment_placeholder, newFrag, "myFrag");
ft.commit();
}
My current solution (which is dirty) is to have a public static String in the same Activity which is checked when the Activity
is resumed, if it is found a search is started using that term and the static variable is cleared out.
public class SearchCatchingActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Ensure this activity isn't in the backstack, notify the previous activity in the backstack that it should handle the search onResume()
DualPaneActivity.searchTerm = getIntent().getStringExtra(SearchManager.QUERY);
finish();
}
DualPaneActivity:
if (!searchTerm.equalsIgnoreCase("")) {
startSearchThread(searchTerm)
searchTerm = "";
}
精彩评论