SharedPreferences sub PreferenceScreen with custom fragment class - android

I have a PreferenceScreen with a sub PreferenceScreen:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="SOUND">
<PreferenceScreen android:title="Sound Options"
android:fragment="com.test.SoundPreferenceFragment">
</PreferenceScreen>
</PreferenceCategory>
...
The sub preference is a custom implementation of a PreferenceFragment
public class SoundPreferencesFragment extends PreferenceFragment implements
OnSharedPreferenceChangeListener {
...
I am wondering how I am supposed to start the custom fragment. In my main activity I do this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, settingsPreference).commit();
}
Which works great to start my main settings preference screen.
I then override:
#Override
public boolean onPreferenceStartFragment(PreferenceFragment fragment, Preference preference) {
getFragmentManager().beginTransaction().replace(android.R.id.content, new SoundPreferenceFragment()).commit();
return true;
}
That seems to work but I have a few questions.
Is that the right way?
When I go into the Sounds preference and hit the back button it takes me all the way out of settings. Is that how it should work?
I think I can also tell the sub preference to start a new intent, i.e. create a new SoundPreferencesActivity. Is that a more 'correct' way.
EDIT:
I also tried not to extend 'onPreferenceStartFragment' in my main activity hoping that android would take care of starting the new preference correctly' It does seem to start the new PreferenceFragment but it overlays the UI right on top of the main preferences UI.

You have to create a new activity and attach the SoundPreferencesFragment .
when you select the item in main setting activity , start the new activity

Related

Save App Preferences from PreferenceScreen when pressing back button

I'm trying to learn how to develop Android apps. I followed a video tutorial on YouTube, and it ended by adding a simple App Settings screen to the application.
However, there's one point that bothers me: when I press the back button on my phone's navigation bar, the changed settings aren't applied.
I have tried searching on Google, but none of the solutions I found have worked. The fact that I don't yet understand 100% of what's happening on the proposed solutions may also contribute to my difficulty on solving this one problem.
The behavior I expect from the app is that when I press the back button on the navigation bar, the changed settings should be applied.
For instance, I have a setting for dark background, which is controlled by a checkbox. The current behavior is: I check the setting for dark background. When I press the back button on the navigation bar, the setting isn't applied (I do have a method that loads the preferences on my MainActivity). What I want to happen is when I press the back button, the dark background is applied in this case.
From what I understand, I believe that overriding onBackPressed should do the trick, but I don't know what should be executed in order to properly apply the settings.
Here are the class and layout of my PreferenceScreen. Regarding the strings on the XML, they aren't actually hard-coded. I just copied the English values here to show the text that should appear on the interface.
public class AppPreferences extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note_detail);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
SettingsFragment settingsFragment = new SettingsFragment();
fragmentTransaction.add(android.R.id.content, settingsFragment, "SETTINGS_FRAGMENT");
fragmentTransaction.commit();
}
public static class SettingsFragment extends PreferenceFragment
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.app_preferences);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="General">
<EditTextPreference
android:title="Notebook"
android:summary="The title that will be used on the main action bar."
android:key="title"
android:defaultValue="Notebook" />
</PreferenceCategory>
<PreferenceCategory
android:title="Color">
<CheckBoxPreference
android:title="Dark Background"
android:summary="Is the main background color dark?"
android:key="background_color"
android:defaultValue="false" />
</PreferenceCategory>
</PreferenceScreen>
You will need to use
public class AppPreferences extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_note_detail);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
SettingsFragment settingsFragment = new SettingsFragment();
fragmentTransaction.add(android.R.id.content, settingsFragment, "SETTINGS_FRAGMENT");
fragmentTransaction.commit();
}
public static class SettingsFragment extends PreferenceFragment
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.app_preferences);
Preference preference = findPreference("background_color");
preference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
//do your action here
return false;
}
});
}
}
}
Or from other activity:
PreferenceManager.setDefaultValues(this, R.xml.your_setting_xml, false);
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
if (settings.getBoolean("background_color", true)) {
//do your action here
.........
Refer to this question also, (it has similar use case):
Checkbox Preference and Checking if its enabled or disable
Like #Chisko said, there isn't enough code in your question for us to be able to figure out your end goal - although I'm guessing you are wanting some form of persistent storage for your app to be able to save your app preferences. For this, you will want to use something in Android called SharedPreferences. This allows you to save simple data types to be accessed later.
Give that link a read, and then try saving/loading one simple piece of data. You'll want to load it from SharedPreferences on starting the activity (you can specify a default value if it hasn't been saved yet) and then you'll want to save the data in onBackPressed() as you said.
Best of luck and if you run into any issues, just comment here.
#Abdulhamid Dhaiban correctly points it out.
I'll add to your suggestion about overriding the onBackPressed() method.
If your "Up" button (top left <-) provides the correct result, then you can set the Back button to behave like the Up button by just adding the following code:
#Override
public void onBackPressed() {
super.onBackPressed();
NavUtils.navigateUpFromSameTask(this);
}
Hope it helps!

Android: How to show title bar in Preferences Fragment

I have searched the forums, but can't seem to figure out how to show a title bar in the Android Preferences Fragment. I see questions about how to hide it, but not about how to show it.
I have a preferences activity
public class SettingsActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content,new SettingsFragment()).commit();
}
}
And I have a preferences fragment:
public class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
And I have a preferences xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="#string/title">
<CheckBoxPreference
android:key="regular"
However there is no title bar at the top of the preferences screen. Any ideas how to make one show?
You mean show title bar in the fragment?
you can try to inherit AppCompatActivity.

Can't accesses setting activity (SharedPreferences)

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.

Button listener not working in Preference fragment

I've created a subclass of PreferenceFragment that implements CompoundButton.OnCheckedChangeListener. I have one preference that contains a Switch (a subclass of CompoundButton). Here's the callback I've created for when the value of the switch changes:
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mAppController.doSomething(isChecked);
Log.v("rose_tag", "hi");
}
I declare the preference in OnCreate as follows:
Switch mySwitch = (Switch) myView.findViewById(R.id.switch);
mySwitch.setEnabled(true);
mySwitch.setOnCheckedChangeListener(this);
The callback gets called when the view first opens (a breakpoint in the callback is hit), but no log prints, and the callback never gets called again, even when I switch the switch on and off. How can I make this callback work?
I also tried creating an inline anonymous listener. I also tried using a simple Button with an onClick listener, and that didn't work either.
I can see you are trying to use PreferenceFragment as any other normal fragment. However, you must to take in count the correct mechanism, one example is you cannot use all the widgets for making a preferences view for the user, you must use the Preference objects (see Preference subclasses).
Another example is that you must use addPreferencesFromResource(int) to inflate preferences from an XML resource.
Check both links above and this example.
I hope It helps you.
If you use the anwser from Jorge Gil, you will not be able to easily get a reference to the view you are declaring in the PreferenceScreen.
However you can easily get one of the preference Object which in that case is a SwitchPreference. So in your res/xml/preferences.xml add your switch preference:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="screen">
<SwitchPreference
android:key="switch_preference"
android:title="title"
android:summary="summary" />
</PreferenceScreen>
Then in your PreferenceFragment/PreferenceActivity's onCreate function add this:
addPreferencesFromResource(R.xml.preferences);
SwitchPreference switchPref = (SwitchPreference) findPreference("switch_preference");
switchPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Log.e(getClass().getSimpleName(),"onPreferenceChange:" + newValue);
return true;
}
});

TabActivity with ActivityGroup and PreferenceActivity child

I have a TabActivity where each tab has ActivityGroup.
On the home ActivityChild of the first group I have an menu option, which gives to the user the option to open preferences.
When I click "Preferences" on menu, I start PreferenceActivity inside ActivityGroup, which shows PreferenceActivity on the first tab.
The problem is when I click on any specific preference which has to show a Dialog (for EditTextPreference).
I have the following exception:
android.view.WindowManager$BadTokenException: Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord#405d3a20
I understand that the problem is because Dialog to be shown by PreferenceActivity uses wrong context, BUT i don't now how change the context of created dialog.
Belows is the PreferenceActivity I've created.
public class PreferencesActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.preferences);
addPreferencesFromResource(R.xml.preferences);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
prefs.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key) {
}
}
I don't want to create custom dialogs. I want to use the mechanism of PreferenceActivity for that.
Below is the code that I'm using to add to group:
i = new Intent(MyActivity.this, PreferencesActivity.class);
TabGroupActivity parentActivity = (TabGroupActivity) getParent();
parentActivity.startChildActivity("PreferencesActivity", i);
Any ideas?
This is very common problem with dialog's in Tab Host.
Actually the Activity context is not sufficient to show a Dialog in Tab.
You have to use the context of your GroupActivity for the dialog to be enabled without exception

Categories

Resources