When I run my application there is no menu button to go to the settings activity.
I have a settings activity which uses shared preferences. I call in the Main Activity like this:
private SharedPreferences settings;
private OnSharedPreferenceChangeListener listener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
settings = PreferenceManager.getDefaultSharedPreferences(this);
listener = new OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
}
};
settings.registerOnSharedPreferenceChangeListener(listener);
And this is my settings activity:
public class SettingsActivity extends PreferenceActivity {
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
}
And my settings.xml is in XML folder and its very simple at the moment. I just want to be able to open settings in my application. The XML is like this:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceCategory android:title="General settings" >
<EditTextPreference
android:key="pref_username"
android:title="User name" />
<CheckBoxPreference
android:key="pref_viewimages"
android:summary="Determines whether lists are shown with thumbnail photo"
android:title="View images"/>
</PreferenceCategory>
I've also added the settings activity to the Manifest file:
<activity
android:name=".SettingsActivity"></activity>
so far it eclipse doesn't show me any errors. But when I run my application there is no menu to go to the settings page! I was under the impression that when I create a settings activity, Android will automatically create a settings menu. But there is no menu button or anything. How can I fix this?
The menu and sharedpreferences are not directly linked. Shared preferences store values inside storage. Menu would be the graphical layout bringing you to PreferenceActivity that allow you to used shared preferences to store the settings.
You have to first inflate the menu like this in your activity :
#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;
}
where menu contains the menu details like these (res/menu/main.xml):
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<<item android:id="#+id/item1" android:title="Your setting name"></item>
</menu>
This would add "Your setting name" as an option when you click the menu button. Now to make the menu button do something use this (put it in your mainactivity) :
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle item selection
switch (item.getItemId())
{
case R.id.item1:
//Do something here like in my case launch intent to my new settings menu
Intent options1 = new Intent(MainActivity.this, SettingsActivity.class);
startActivity(options1);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Now the menu button called "Your setting name" will launch your settings activity.
I don't think it's created by default. I had to do it myself. Anyway, check the menu file for your activity and check if this menu is used in your activity.
Related
I started my project with the template "Tabbed Activity" and am now trying to add an options menu. I have done this before with a blank activity and it worked fine. As far as I can tell I have done all the same steps, even as outlined by the documentation: https://developer.android.com/guide/topics/ui/menus#options-menu
When I run the app, nothing shows up. I would expect to see the 3 dots icon. I also tried adding icons to see if they would show up as actions. No luck. Here's what I've got in my MainActivity.java file:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu_layout, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId())
{
case R.id.settingsMenuItem:
ShowSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void ShowSettings() {
// TODO show settings
}
}
And this is the options menu xml file which is "options_menu_layout.xml" located in the res/menu directory:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/settingsMenuItem"
android:icon="#drawable/baseline_settings_black_48"
android:title="#string/menu_option_settings"/>
</menu>
This seems to work on a blank activity, but not in this tabbed activity. Is there something I'm missing that is required to make these compatible?
show the xml, style and manifest files.
According to the documentation of onCreateOptionsMenu(),
"You must return true for the panel to be displayed; if you return false it will not be shown."
In your code sample, you have return super.onCreateOptionsMenu(menu);.
Is there a reason for calling the parent's class method as well? (The android developer guide code sample also does a return true;)
So I would first try to change onCreateOptionsMenu() to return true; to see if the options menu shows up and as a next step investigate the need to call the parent class' super.onCreateOptionsMenu(menu).
Turns out when using the template "Tabbed Activity" the manifest file uses a "NoActionBar" version of the theme.
I deleted the last part of this line:
android:theme="#style/Theme.ExampleApp.NoActionBar">
So it is this instead:
android:theme="#style/Theme.ExampleApp">
I am trying to add a page in "Settings" menu option on top of the android app. The app by default had the 3 dots on top right corner and when I click on it, it doesn't go anywhere and now I am trying to implement settings to my app. What I have done so far is following,
Created xml file in /res/xml folder called preferences.xml with following content;
<?xml version="1.0" encoding="utf-8"?>
<preferencescreen xmlns:android="http://schemas.android.com/apk/res/android">
<preference android:key="sample"
android:summary="can open other activity"
android:title="click here">
</preference>
<edittextpreference android:key="Name"
android:summary="Add user Name."
android:title="Your Name">
</edittextpreference>
</preferencescreen>
Then I have created a new java class called Preferences in /src/main/java/package/ with following content;
package com.domain.mobile.tipcalculator.app;
import android.preference.PreferenceFragment;
import android.os.Bundle;
public class Preferences extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
Then to my understanding this is all I need. I m not getting any errors on compilation time but when I click on the 3 dots on top right and click on "Settings" I still don't see the page come up. Any ideas? Thank you.
P.S. I am using PreferenceFragment because my min sdk requirement is 11.
To use menus like that, you have to create a menu xml file then inflate it and then switch between the menu item ids so that you can handle click events like the following:
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.preferences:
startActivity(new Intent(this, PreferenceActivity.class));
return true;
case R.id.settings:
startActivity(new Intent(this, SettingsActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
You should be able to achieve what you need this way and I hope this helped.
When using the Android Eclipse IDE, how do I add a menu that is triggered by the phone menu button such that it has to have an "About" choice that displays an "About my app" dialog and a "Quit" choice that exits the app?
To create a content menu with about a quit items, please add all of the following to your project after first removing any other attempts at an about menu that might potentially conflict with this code. Let Eclipse help you add the required imports or peruse the android documentation as you try to build this, and after everything's in place it should just work :-)
In /res create a folder menu containing a file main.xml with the following xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="#string/action_settings"/>
<item
android:id="#+id/action_quit"
android:orderInCategory="101"
android:showAsAction="never"
android:title="#string/action_quit"/>
</menu>
In MainActivity.java add the following after your onCreate is closed:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
AboutDialog about = new AboutDialog(this);
about.setTitle(“About “my app);
about.show();
return true;
case R.id.action_quit:
System.exit(0);
return true;
}
}
Add a new java file but extend Dialog instead of Activity, like shown:
public class AboutDialog extends Dialog {
public AboutDialog(Context context) {
super(context);
}
#Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.dialog_about);
}
}
Finally, add a new layout dialog_about.xml like so:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/ScrollView01"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ScrollView>
Of course you’ll need to add another layout and content inside the ScrollView, and you may want other features in your menu and your quit item could use a confirmation (possibly). But this should get you started.
I've implemented my preferences like shown in the official guidelines.
I have a PreferenceActivity which creates the PreferenceFragment like this:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if (extras != null)
{
Bundle bundle = new Bundle();
_widgetID = extras.getInt(GlobalSettings.EXTRA_WIDGET_ID);
bundle.putInt(GlobalSettings.EXTRA_WIDGET_ID, _widgetID);
WidgetSettingsFragment fragment = new WidgetSettingsFragment();
fragment.setArguments(bundle);
getFragmentManager().beginTransaction().replace(android.R.id.content,
fragment).commit();
}
}
The PreferenceFragment loads the preferences from the resources and they contain a preference subscreen like this:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!-- opens a subscreen of settings -->
<PreferenceScreen
android:key="button_voicemail_category_key"
android:title="#string/voicemail"
android:persistent="false">
<ListPreference
android:key="button_voicemail_provider_key"
android:title="#string/voicemail_provider" ... />
<!-- opens another nested subscreen -->
<PreferenceScreen
android:key="button_voicemail_setting_key"
android:title="#string/voicemail_settings"
android:persistent="false">
...
</PreferenceScreen>
<RingtonePreference
android:key="button_voicemail_ringtone_key"
android:title="#string/voicemail_ringtone_title"
android:ringtoneType="notification" ... />
...
</PreferenceScreen>
...
</PreferenceScreen>
This works well so far, but now I'd like to have an up-Button in the actionBar when the preferences subscreen is shown. Any idea how to accomplish that?
I have tried to set setDisplayHomeAsUpEnabled(true) in my activity but then the up-Button is only shown in the main preferences (where it should not) and not in the subscreen.
I'm wondering that even in the official docs the subscreen is shown without an active up-Button:
Link to the docs: Settings
Any help is really welcome
I finally got it to work :D. It's quite hacky but it works.
The problem is, that using subscreens in xml-layouts results in some 'code magic'.
A new activity/dialog is started for the subscreen and you don't have direct access to it.
To get access to the actionbar and the OnClickListener of the home/up-button you need to get a reference to your PreferenceScreen and get its parent Dialog in order to access the actionbar and its home/up button.
This is how it is done inside my PreferenceFragment:
#Override
public void onCreate(Bundle savedInstanceState)
{
...
final PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference(getString(R.string.keyPrefScreenDynamicWidgetDetails));
preferenceScreen.setOnPreferenceClickListener(new OnPreferenceClickListener()
{
public boolean onPreferenceClick(Preference preference)
{
preferenceScreen.getDialog().getActionBar().setDisplayHomeAsUpEnabled(true);
final Dialog dialog = preferenceScreen.getDialog();
View homeBtn = dialog.findViewById(android.R.id.home);
if (homeBtn != null)
{
OnClickListener dismissDialogClickListener = new OnClickListener()
{
#Override
public void onClick(View v)
{
dialog.dismiss();
}
};
// Prepare yourselves for some hacky programming
ViewParent homeBtnContainer = homeBtn.getParent();
// The home button is an ImageView inside a FrameLayout
if (homeBtnContainer instanceof FrameLayout) {
ViewGroup containerParent = (ViewGroup) homeBtnContainer.getParent();
if (containerParent instanceof LinearLayout) {
// This view also contains the title text, set the whole view as clickable
((LinearLayout) containerParent).setOnClickListener(dismissDialogClickListener);
} else {
// Just set it on the home button
((FrameLayout) homeBtnContainer).setOnClickListener(dismissDialogClickListener);
}
} else {
// The 'If all else fails' default case
homeBtn.setOnClickListener(dismissDialogClickListener);
}
}
return true;
}
});
...
}
Following link gave me the final hints and code to solve my problem:
Action Bar Home Button not functional with nested PreferenceScreen
I do this per the Android docs in the "Supporting older versions with preference headers" section http://developer.android.com/guide/topics/ui/settings.html#BackCompatHeaders. Using the legacy PreferenceActivity, you specify a Preference in the xml that launches an intent to the same preference activity class. The activity checks the intent action and determines if it is nested or not (to show the up button) and which preference xml to inflate in the screen.
Of course, I intend to support older devices as well. I have found that the PreferenceFragment is only useful for large tablets that use preference headers.
To reuse preferences between phones and tablets I came up with this solution https://stackoverflow.com/a/20806812/1139784
To enable the up action do the following:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayUseLogoEnabled(true);
this will give you the icon.
then add
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
you can alter this to go where you need to. As another option you can use the navigateUpTo(Intent intent) and the onSupportNavigateUpTo(Intent intent) methods and specify the intent you want to return to.
I have a menu that comes up for my PreferenceActivity. In my child preference screens, I lose that menu (doesn't pop up). How can I make my menu pop up for children too?
Thanks.
Example:
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:persistent="true">
<PreferenceCategory
android:title="some category"
android:persistent="true"
android:orderingFromXml="true">
<PreferenceScreen
android:title="some child screen"
android:summary="some child summary">
<PreferenceCategory
...
The first preference screen has the menu, but when you click on the child one, no menu. How can you add the menu?
I have better solution because Suriya's suffer from double showing of child's PreferenceScreen.
For child PreferenceScreen I use same PreferenceActivity. So at first for a child PreferenceScreen where we want to use option menu we set intent to our PreferenceActivity in onCreate method:
ourPreferenceScreen = (PreferenceScreen) findPreference("our_preference_screen");
if (ourPreferenceScreen != null) {
Intent intent = new Intent(this, PreferenceActivity.class);
intent.putExtra("ShowOurPreferenceScreen", true);
ourPreferenceScreen.setIntent(intent);
}
Then later in a same onCreate method we detect if our PreferenceActivity is started with extra flag. If so we switch to wanted PreferenceScreen:
if (getIntent().getBooleanExtra("ShowOurPreferenceScreen", false)) {
setPreferenceScreen(ourPreferenceScreen);
return;
}
And at the end we hande onCreateOptionMenu and other related option menu methods like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (getPreferenceScreen().equals(ourPreferenceScreen)) {
// your menu code
return true;
}
return super.onCreateOptionsMenu(menu);
}
I faced the similar issue. Here is what I did to overcome the issue.
In the preferenceActivity onCreate method,
final PreferenceScreen childPref = (PreferenceScreen) findPreference("childPrefId");
childPref .setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference)
{
Intent intent = new Intent(PreferenceActivity.this, YourSettings.class);
intent.setAction("ShowChildPref");
startActivity(intent);
return true;
}
});
Intent intent = getIntent();
if(intent.getAction() != null && intent.getAction().equals("ShowChildPref"))
{
setPreferenceScreen(childPref);
/*Set Flags here based on intent what kind of menu to create in OnPrepareMenu.*/
}
}
You have to add the code for the menu in each class that might want to bring up a menu using the menu button. Just because the other activity is in the background does not mean the menu will launch. It needs to be set in each class that wil be forground and need the menu available.