Android: Send info from activity to fragment - android

In my MainActivity I have an active search button on my Action Bar/Tool bar/menu. I was wondering if there is a way to filter a list in a Fragment form that active search? Thanks in advance!
It would be even better if each fragment (they are in a viewpager + action bar with tabs) Can have its own action bar!

You should create a custom adapter for your activity's view pager
Then show fragments from adapter, now you have 2 choices for your purpose :
define custom toolbar for each fragment in it's own layout (.xml) file and then use it or
pass data from activity to fragment adapter and from fragment adapter to your purpose fragment(s) and do filtering.
Good Luck my friend

If you do not want to implement using a system service for searching as described in docs, then one way of doing it would be as follows:
In the onCreate method get a handle to your fragment
// if you fragment is embedded with <fragment tag>
mMySearchFragment = (MySearchfragment)getFragmentManager()
.findFragmentById(R.id.your_fragment)
//in case your fragment is added programmatically then, of course,
getFragmentManager()
.beginTransaction()
.add(fragmentid, gragmentinstance, TAG)
.commit();
In the onCreateOptionsMenu do something like
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_searching, menu);
mSearchView = (SearchView) menu.findItem(R.id.menu_search_message).getActionView();
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
#Override
public boolean onQueryTextSubmit(String query) {handleSearch(query)}
#Override
public boolean onQueryTextChange(String newText) { ... }
});
return true;
}
And finally
private void handleSearch(String query){
if(mMySearchFragment != null){
mMySearchFragment.updateSearchResults(query);
}
}
Your fragment would need to have a public method updateSearchResults(String query) where you would run the search and update your list view's adapter with the new collection
Also, you can import the BasicContactables sample in the Studio (File -> Import Sample) and investigate the code

Related

Using single SearchView in Activity, for different fragments

I'm trying to use one searchview from actitivity toolbar menu, to filter three fragments attached to it (It's a tabbed activity) at the same time and categorizing the results in the different fragments . Kind of like the way Instagram does theirs. I've tried inflating the onCreateOptionsMenu in each fragment, but this just starts a new instance of the search i.e (search icon is .istIconified(); I want the differnt tabs to show the query text of what ever was typed in it and perform the search at the same time.Can't seem to find this solution on SO, Any help or resource will be very much appreciated
Well it is possible.
first of all use "setOnQueryTextListener"
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
Log.i("well", " this worked");
return false;
}
});
}
After that pass this string to currently selected fragment by calling fragment method from the activity. click here to check how to call fragment method from activity
From fragment method you can do anything which you want to do for.

How can I send information from my searchview in my main actiity to one of the fragments from my viewpager

My main activity has a viewpager with 3 fragments. In fragment1 I have a recyclerview that shows some information. Back into my main activity I have a searchview, my question is how can I pass the information from my mainactivity to the fragment1 so I can update my recyclerview based on what the user put in the searchview.
I already have the searchview and the listener with onQueryTextSubmit and onQueryTextChange methods to get the string from the searchview
Thank you.
You can use the FragmentPagerAdapter as a bridge. Add a method to your FragmentPagerAdapter:
public void onQueryTextChange(String text) {
fragment1.onQueryTextChange(String text);
}
In fragment1 you should also add a method:
public void onQueryTextChange(String text) {
//do something
}
Then in your Activity, when search text changed, call:
theAdapter.onQueryTextChange(text);

Android setting share option visibility on fragments managed by tabs in sliding tab layout

I have been struggling to implement switching visibility of Share option on Menu between fragments. I am using sliding tab layout and has a fragment in each of the 2 tabs. First tab (uses list view) and when an item is selected, I am setting a flag as true and calls invalidateOptionsMenu() and it works fine by showing a share option on the App bar menu, but I am not able to cancel it when I move to the other fragment which has mainly preferences. Code is similar to the below.
public void setSharedIntentText(String text) {
sharedText = text;
if (shareOptionVisibility == false) {
shareOptionVisibility = true;
invalidateOptionsMenu();
}
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
// Locate MenuItem with ShareActionProvider
MenuItem shareItem = menu.findItem(R.id.menu_share);
// Fetch and store ShareActionProvider
mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem);
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_TEXT, sharedText);
mShareActionProvider.setShareIntent(sendIntent);
shareItem.setVisible(shareOptionVisibility);
When I switch between tabs, visibility should be set appropriately. I tried to set it onPause method of the first fragment, and then onResume method of second fragment, but control doesn't seem to go these methods when I look at the logcat. The code I have used to set visibility to false is as below in fragment2.
public void onResume() {
super.onResume();
Log.i(TAG, "On Resume ");
((MainActivity) getActivity()).shareOptionVisibility = false;
((MainActivity) getActivity()).invalidateOptionsMenu();
}
So would like to know where is the best place to put the code to control visibility when we switch between tabs. Here are the list of classes I use.
MainActivity, fragment1, fragment2, SlidingTabLayout, SlidingTabStrip and ViewPagerAdaptor. This code was implemented on top of the com.example.android.actionbarcompat.shareactionprovider example.
Thanks in advance
Issue now resolved by implementing the onCreateOptionsMenu method from the fragment rather than from the MainActivity.
Thanks

Interaction between Activity and Fragments

In my application the main activity hosts two fragments and attached to acticity as ActionBarTabs. using the following code. NOTE: activity and the 2 fragments are defined in seperate xml layout files (See the picture at the bottom)
private void createActionTabs() {
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//Status Tab
String strStatus = getResources().getString(R.string.lblStatus);
ActionBar.Tab statusTab = actionBar.newTab();
statusTab.setText(strStatus);
TabListener<SFrag> sFTabListener = new TabListener<SFrag>(this, strStatus, SFrag.class);
statusTab.setTabListener(sFTabListener);
actionBar.addTab(statusTab);
//Controller Tab attached the same way
.....
}
The ActionBar Items (start and refresh) are added using
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
Now coming to my problem:
I want to update the data shown on the Status Fragment at application load, fragment resume and click of refresh menu item from the action bar. Now when I try to access the Status fragment from Main Activity using the following code
SFrag frag = (SFrag) getFragmentManager().findFragmentById(R.id.st_frag);
Log.d(TAG, "In Activity SFrag is " + (frag == null ? "null" : "not null"));
if (frag != null) {
//calls the method to update data
fragment.updateStatusData(statusInformation);
}
The getFragmentManager().findFragmentById methods always returns null. I even tried the onResume method of the activity, the fragment objects is still returned as null. So how do I access the fragment and thus accessa method of that fragment from host acticty.
Secondly, I am trying to use the action_service (its shown as Start button just for this mockup) in action bar as a toggle for satrting or stopping a background service. I can easily update the title/icon for start menu item from onOptionsItemSelected method (I save the current status running/stoppede in shared-preferences). but when I try to accees the menuItem at onStart/onResume of the activity by using
MenuItem mi = (MenuItem) findViewById (R.id.action_service);
it always returns null. So How Can I access action_service menu Item in onResume/onStart to update it.
My Application looks like this
First of all if you want to declare MenuItem, you should do it in this way :
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.main_activity, menu);
MenuItem mRefresh = menu.findItem(R.id.refresh_menu_item);
return true;
}
About updating your Fragment on applications load or Activity's start, just set selected the tab which holds your Fragment and put the code which will load the data in your Fragment on it's onStart() or onActivityCreated() method. You can override onOptionsItemSelected() in your Fragment, so you can update your views not from your Activity which holds your Fragment, but from it's own class.
Edit: Here is an example how you should handle menu from your Fragment :
public class MyFragment extends Fragment {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true); // Do not forget this!!!
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.first_fragment, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.action_refresh:
// Do You stuff here
break;
}
return super.onOptionsItemSelected(item);
}
}
Using this you can add and use MenuItem's in your Fragment.
Hope this helps!
I can answer the MenuItem part just not the other part.
for the menu item as per the docs You can safely hold on to menu (and any items created from it), making modifications to it as desired, until the next time onCreateOptionsMenu() is called.
for example
#Override
public boolean onCreateOptionsMenu(Menu menu) {
actionMenu = menu;
return true;
}
so basically anytime you want to change one of the items you can do this
MenuItem item = actionMenu.getItem(0);

FragmentStatePageAdapter duplicates ActionBar menu items

I have a problem with FragmentStatePageAdapter (that I use as adapter for a ViewPager) and the menu items from the action bar.
When I launch the application, everything is fine. If I move the task to background (for example, pressing HOME button) and I start doing stuff until the activity is ended, then when I go back to my application (through the launcher or a notification I create) everything is fine except there are duplicated menu items in the action bar.
An important detail is that the only duplicated items are those that are created in the onCreateOptionsMenu() of each fragment I use in the ViewPager.
If I replaceFragmentStatePageAdapter with FragmentPageAdapter the items are not duplicated anymore, but the fragments are not shown in the ViewPager (getItem() function from the adapter is never called so it does not return any fragment).
Any ideas? A way to avoid FragmentStatePageAdapter to duplicate menu items? Maybe use FragmentPageAdapter but with a modification to show the fragments? A modification in my fragments?
Here are some code snippets from my application...
How menu items are created inside the fragments:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
/* Create play button */
final MenuItem mPlay = menu.add(R.string.play_all);
mPlay.setIcon(R.drawable.ic_play_all);
mPlay.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
mPlay.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
final List<Song> songs = getSongs();
if (songs.size() == 0) {
/* Show message */
Toast.makeText(mContext, R.string.no_song_list, Toast.LENGTH_LONG).show();
} else {
/* Play song list */
try { PlayManager.getService().playList(songs); } catch (Exception e) {}
}
return false;
}
});
/* Create menu */
super.onCreateOptionsMenu(menu, inflater);
}
How fragments are instantiated in the ViewPager adapter
#Override
public Fragment getItem(int position) {
final Class<?> cls = mTabs.get(position);
/* No tab */
if (cls == null)
return null;
/* Instantiate fragment */
final Fragment fragment = Fragment.instantiate(mContext, cls.getName(), null);
/* Add to list */
mFragments.put(position, fragment);
/* Return fragment */
return fragment;
}
Thanks!
PS: I tried to change the launchMode of the activity to "singleTop" and I also tried to return in getItem() the previosly created fragment (but that's useless as getItem() is never called when I return to the application, as I said before).
I found a solution to my problem a few days after posting my problem. I'm sorry for putting it here so late.
The following code fixed my problem:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.remove("android:support:fragments");
}
As simple as writing that piece of code in the activity where I instantiate and use the fragments.
I hope this helps :)
Before inflating the options menu in your Fragment inside the ViewPager, check whether the Fragment instance is visible to prevent duplicated menu items:
// This should be in your Fragment implementation
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
if(isVisible())
{
inflater.inflate(R.menu.menu_fragment, menu);
}
super.onCreateOptionsMenu(menu, inflater);
}
I assume the problem is that the FragmentStatePagerAdapter creates a new Fragment each time you swipe. As a result, onCreateOptionsMenu() is called for each Fragment that is created.
There are, I think, two solutions:
Take the action bar manipulation out of the Fragments. Instead of setting an onclick for the menu item inside of the Fragment, you send a message to the current Fragment from the Activity.
Use Menu.findItem() to see if another Fragment has already added the MenuItem you want, and if so attach the current Fragment to it (in onPrepareOptionsMenu()).
I found some solution try it may be work
In your duplicate menu fragment
Add menu.clear() before inflate menu file in onCreateOptionsMenu(Menu menu, MenuInflater inflater)
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.main,menu);
}

Categories

Resources