I'm programming an app based on the Weather App from Udacity Courses.
The app is based in a two activies: one general and other for weather detail with a fragment inside.
I've been experimenting with menu creation and I have and issue that I would like to comment with you all.
AFAIK, If I want to share an option between different fragments, it seems a good idea to put that option in the activity menu instead of the fragment menu, so that's what I'm doing with the Share button.
But I've seen that I have two possible situations:
1) If the menu item inside the xml is declared as showAsAction = never I can create the instance of the ShareActionProvider and the intent inside the onOptionsItemSelected, within the corresponding if sentence (and works fine):
public class DetailActivity extends Activity {
ShareActionProvider mShareActionProvider;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
getActionBar().setDisplayHomeAsUpEnabled(true);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction().add(R.id.container, new DetailFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.detail, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
startActivity(new Intent(this, SettingsActivity.class));
return true;
}
if (id == R.id.action_share) {
mShareActionProvider = (ShareActionProvider) item.getActionProvider();
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, "nada");
mShareActionProvider.setShareIntent(shareIntent);
return true;
}
return super.onOptionsItemSelected(item);
}
2) If the menu item is declared as showAsAction = always and the Share button is in the action bar, the above doesn't work as the Share button isn't even clickable. I have to declare the above code inside the onCreateOptionsMenu to make things work.
Why is that? Is different the chain of events for creating a menu when is not in the action bar Vs. when it's in it?
Thanks for the answers and excuse me for my english.
Related
I have an Activity that has a tabhost and a ViewPager that support 3 fragments. I want to use the ActionBar (which resides in the Activity) to use and modify menu items selectable from the ActionBar directly in each of the fragments.
What is the best way to send a message from the activity to the fragment to tell it to implement one of the actionbar items?
I have tried the following:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
FragmentManager manager = getSupportFragmentManager();
List<Fragment> fs = new ArrayList<>(manager.getFragments());
int fragId = fs.get(0).getId();
PlayFragment fragment = (PlayFragment) manager.findFragmentById(fragId);
fragment.settingsMenu();
return true;
This is not working, but also is bad form to need to know the order of the fragments to get it to work. This way didn't work for me. I know I could use a broadcastSender to make it work, but that is also bad form. The REAL problem here is that since the fragments are sitting on top of a ViewPager within a TabHost, there is no way to get the id or tag reliably, so
manager.findFragmentById(fragId) and
manager.findFragmentByTag("MyFragmentName") are not useful.
When I try to attach the toolBar to an OnClickListener within the fragment, it doesn't work, and fragment has no support for
#Override public boolean onOptionsItemSelected(MenuItem item);
I'll keep looking for a solution. Thanks.
I found the answer on another post. The trick is to get the toolbar from the activity but not to use it as an actionbar directly. You need to inflate your own menu, and have access to modifying title etc ;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.play_fragment, container, false);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = JamSessionApplication.getInstance();
toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
toolbar.setTitle(song);
// Set an OnMenuItemClickListener to handle menu item clicks
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_reverb) {
Toast.makeText(getActivity(), "Reverb", Toast.LENGTH_SHORT).show();
return true;
}
return true;
}
});
toolbar.inflateMenu(R.menu.menu_play);
}
I still encountered problems with ViewPager/Tabhost toobars working properly. I found an article which was much more helpful in fixing this.
https://www.numetriclabz.com/android-tabs-with-fragments-and-viewpager-tutorial/
When I minimize, the data like score and position of objects are reset. When I lock the screen the app is restarted. Is there a way to save all objects data to make their positions and score be the same after resume? And how I can make the blockscreen button(same as wait for lockscreen) dont make the app restart. Is it possible to disable the auto lockscreen through the application?
Sorry if asking too much, I'm new here and I couldn't find what I want in other questions.
Here is my Activity class:
`public class Home extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(new GamePanel(this));//GamePanel is the SurfaceView
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_home, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}`
I think you should go with saveInstanceState and restoreInstanceState.
Checkout "Save Your Activity State" at http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
I'm following a course on Udacity on building an Android app (weather, in this case). I've been having trouble implementing a Share action. After getting some advice from another forum, I changed the min SDK version from 10 or 11 to 17, since this is just a learning activity. Currently, I have the "Share" button showing up in the action bar, but tapping on it does nothing. I tried putting it in the overflow menu, but still, nothing. I tried some debugging, but I don't know where the button click is supposed to be handled; the debugger goes through and creates the shareIntent object, but then nothing seems to happen with it. I looked at this doc, but when I try to handle the sharing in the view's onOptionsItemSelected, I get a null pointer exception on the call to createShareIntent. What am I missing?
Here's the nested fragment's onCreateOptionsMenu:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.detail_fragment, menu);
MenuItem item = menu.findItem(R.id.action_share);
ShareActionProvider mShareActionProvider = new ShareActionProvider(getActivity());
if(mShareActionProvider != null) {
mShareActionProvider.setShareIntent(createShareIntent());
} else {
Log.d(LOG_TAG, "Share action provider is null");
}
}
Here's the containing view's onOptionsItemSelected, with the problematic code commented out:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
startActivity(new Intent(this, SettingsActivity.class));
return true;
} else if (id == R.id.action_share) {
//DetailFragment details = (DetailFragment) getFragmentManager().findFragmentByTag("detailFragment");
//startActivity(details.createShareIntent());
}
return super.onOptionsItemSelected(item);
}
And here's the createShareIntent method:
private Intent createShareIntent() {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, mForecastStr + FORECAST_SHARE_HASHTAG);
return shareIntent;
}
Currently, I have the "Share" button showing up in the action bar, but tapping on it does nothing.
Make sure you are going through your code branch that calls setShareIntent(), and make sure that the device or emulator you are testing on has an activity from some app that supports ACTION_SEND for text/plain. Also, if there is only one activity that supports ACTION_SEND for text/plain, the icon for that activity will appear adjacent to the ShareActionProvider share icon, and you would tap the activity icon to share with that activity.
I tried some debugging, but I don't know where the button click is supposed to be handled
That is inside the implementation of ShareActionProvider.
I looked at this doc, but when I try to handle the sharing in the view's onOptionsItemSelected, I get a null pointer exception on the call to createShareIntent.
onOptionsItemSelected() is for regular action items, not action providers.
It turns out I had put android:actionProviderClass="android.widget.ShareActionProvider in a layout XML file instead of a menu one. I don't think the Udacity course I'm taking mentioned the correct location for that (perhaps due to compatibility things).
In my app, I have an icon in the action bar. When I click on it, I get an option called Settings. However, when I click on this option, nothing happens. I have searched, but I can't find out how to utilize this option. I would like for a dialog box to open when Settingsclicked (or if another Activity opened that would be cool too), which I could then add content to. Does anyone know how I would go about this?
The solution Dave S provided works but I want to share another way you can handle this functionality.
In your Activity you can have the following code to interact with your menu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
displaySettingsDialog();
}
return super.onOptionsItemSelected(item);
}
The key is to make sure you are checking for the right ID you assigned to your menu item.
If you wanted to launch a new activity (SettingsActivity) then you can replace the displaySettingsDialog() function with the following:
Intent intent = new Intent(this, SettingsActivity.class)
startActivity(intent);
Look for main.xml in your res/menu/ folder. (at least for eclipse ADT) There you can specify an onClick attribute which will call a function in your code. from there you can do whatever you want with it.
EDIT
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity" >
<item
android:id="#+id/fb_login"
android:orderInCategory="100"
android:showAsAction="never"
android:title="#string/facebook_login_label"
android:onClick="showFacebookDialog"/>
</menu>
This would define the item for my MainActivity, inside which you define the onClick like so
public void showFacebookDialog(final MenuItem item)
{
...
}
In my application, I have created a class Base_Activity extending SherlockFragmentActivity in which I have defined an action bar this way (it is a menu bar with three different items):
public class Base_Activity extends SherlockFragmentActivity {
private ActionBar mActionBar;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getSupportMenuInflater().inflate(R.menu.main, menu);
mActionBar = getSupportActionBar();
mActionBar.setDisplayUseLogoEnabled(false);
mActionBar.setDisplayShowCustomEnabled(true);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.home:
Intent i = new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
return true;
case R.id.map:
Intent ii = new Intent(this, MainActivity.class);
ii.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(ii);
return true;
case R.id.favorites:
Intent iii = new Intent(this, FavoritesListView.class);
iii.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(iii);
return true;
default:
return super.onOptionsItemSelected(item);
}
} }
Then I have added this line to set this bar in the bottom of my application :
android:uiOptions="splitActionBarWhenNarrow"
It's working well, so far I don't have any problems : I have my bottom action bar with listener for every button.
I now want to add a top action bar, with a SearchBar (or SearchWidget) and a item opening a submenu in the up-right corner.
My problem is now : at the top of every activity, instead of the useless bar with the name of each activity, I want to have another top bar with :
1/ A search bar
2/ An icon opening a sub-menu in the up-right corner.
Unfortunately, I often read that it's not really possible but many application do use this. I am really having a hard time finding how to add my search bar, which doesn't make sense : I know how to write my query method, I have my databaseAdapter and Helper class, so basically it's just about displaying a simple search bar on the top, putting a listener and sending my query to the database and then display a list view.
Does anyone know something which can do the trick to keep an action bar on the bottom and have a search bar also on the top ? Thanks !
See my question. I think will answer for your first question. Second is very similar to this what I need.