Adding a TextView inside a PreferenceScreen's Preference - android

In this preferenceScreen the user unlinks the device from his account. At the moment I just have it as Unlink device, once the user clicks it, the unlinking happens.
But I would like to add a piece text like this:
Joe Foo's Device (joefoo#gmail.com) - Unlink Device
Hoe would I do this? I also need to add the user name dynamically from settingsActivity.
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<Preference android:title="#string/pref_title_advanced_unlink" >
<TextView somehow must be in here
android:id="#id/user_name_and_email" />
<intent android:action="android.intent.action.VIEW"
android:targetPackage="com.example.tvrplayer"
android:targetClass="com.example.tvrplayer.UnlinkActivity"
android.setflags="FLAG_ACTIVITY_CLEAR_TOP"/>
</Preference>
</PreferenceScreen>

preferences.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:key="pref_title_advanced"
android:title="Advanced" >
<CheckBoxPreference
android:defaultValue="false"
android:key="pref_title_advanced_link"
android:title="Link Device" />
</PreferenceCategory>
</PreferenceScreen>
PrefsActivity.java
private SharedPreferences mPreferences;
private SharedPreferences.OnSharedPreferenceChangeListener mPrefListener;
private CheckBoxPreference mCheckBoxPref;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
mCheckBoxPref = (CheckBoxPreference) getPreferenceScreen().findPreference(
"pref_title_advanced_link");
/*
* set initial summary as you desire. For example, userIdCurrent can be:
* "No Devices linked."
*/
mCheckBoxPref.setSummary(userIdCurrent);
mPrefListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs,
String key) {
if (key.equals("pref_title_advanced_link")) {
/*
* set post-click summary as you desire. For example,
* userIdPost can be:
* "Joe Foo's Device (joefoo#gmail.com)".
*/
mCheckBoxPref.setSummary(userIdPost);
}
}
};
mPreferences.registerOnSharedPreferenceChangeListener(mPrefListener);
}

Preferences have a subtitle called summary. Give your preference a key, then you can use findPreference(CharSequence key) in your PreferenceFragment to get a reference to your preference object, sort of like calling findViewById to get references to Views. Then call setSummary(int) or setSummary(CharSequence) on the preference object.
Alternatively, you could do something entirely more complex by providing a custom layout for your preference objects and/or subclass Preference and implement some custom data binding. But I think the above should do what you want.

Related

Making PreferenceScreen not write to default SharedPreferences

I have a PreferenceScreen:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:id="#+id/checkBoxHighlightWeekends"
android:key="checkBoxHighlightWeekends"
android:summary="Weekends are different"
android:title="Highlight weekends" />
<MultiSelectListPreference
android:id="#+id/multiSelectListSelectWeekends"
android:key="multiSelectListSelectWeekends"
android:dialogTitle="Select weekends"
android:entries="#array/weekends"
android:entryValues="#array/weekends_values"
android:summary="Saturday, Sunday"
android:title="Select weekends"/>
</PreferenceScreen>
I'm trying to use only the "view" part of this and not make it write to it's default SharedPreferences. When user changes the preference, I manually check the changed data and send it to a MVVM repo, when then writes to my own custom SharedPreference. I plan to use LiveData to update the settings screen when it's opened. All this hassle because I'm trying to learn the MVVM architecture and Android in general.
Inside MainPreferenceFragment:
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings_main);
CheckBoxPreference checkBoxHighlightWeekends = getPreferenceManager().findPreference("checkBoxHighlightWeekends");
MultiSelectListPreference multiSelectListPreference = getPreferenceManager().findPreference("multiSelectListSelectWeekends");
checkBoxHighlightWeekends.setOnPreferenceChangeListener(changeListener);
multiSelectListPreference.setOnPreferenceChangeListener(changeListener);
}
Preference.OnPreferenceChangeListener changeListener = new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object o) {
// Call method in ViewModel which will save settings state to SharedPrefs
Logger.alert("Something changed! " + preference.getKey());
return true;
}
};
Any change to settings triggers the function, however the checkbox stops working - It doesn't change to the "tick" state anymore.
How can I strip out all the default click/change functionality from the PreferenceScreen and make it into a dumb view?

Preference key always return null

I have a Preference Screen in my android app which contains a call to the system settings via an inner Preference and some Switches options as below:
<PreferenceCategory
android:title="#string/preferences_activity_supervisor_settings_title">
<Preference
android:key="#+id/instrument_preference"
android:title="#string/instrument_settings"
android:summary="#string/instrument_settings">
</Preference>
<com.CustomSwitchPreference
android:key="#string/prefs_super_autosend_key"
android:title="#string/prefs_super_autosend_title"
android:summary="#string/prefs_super_autosend_summary"
android:defaultValue="false"/>
...
...
My class extends PreferenceFragment and I added the resources using addPreferencesFromResource(). It works without problems.
However, the method onPreferenceTreeClick(), when I click in the Fragment (keyID = instrument_preference) the preferences always brings me key as NULL. All other options in the preference fragment I can read the key.
The question is why and how I detect the user clicked in the first element of my preference list ?
First remove + from #+id, because every time it create a new key due to #+id, thats why you get null.
And to detect SharedPreference is changed use this simple code:
public class MyPreferences extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.fw_preferences); //deprecated
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
// handle the preference change here
}
}
Try removing #+id before the preference key name
It should be like
<Preference
android:key="instrument_preference"
android:title="#string/instrument_settings"
android:summary="#string/instrument_settings">
</Preference>

Get to default shared preferences without invoking PreferenceActivity

I have the following PreferenceActivity defined:
public class HiddenPreferences extends PreferenceActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.hidden_prefs);
}
}
where the hidden_prefs.xml looks something like this:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference android:key="testRestUrl"
android:title="REST service URI"
android:defaultValue="http://service/url">
</EditTextPreference>
</PreferenceScreen>
now I set the values to default and would like to read this preference in some other activity, like this:
PreferenceManager.setDefaultValues(this, R.xml.hidden_prefs, false);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
but when calling:
prefs.getString("testRestUrl", "");
I need to give the default value as second parameter, and the call always returns "" (as given in the call) but not the default value as given in the XML android:defaultValue attribute.
How should the preference be access in order to get the default value?
I don't believe you can do this if you don't instantiate the PreferenceActivity.
Your best bet is to define a String in strings.xml or config.xml and use R.strings.testRestUrl in your code:
prefs.getString("testRestUrl", getString(R.string.testRestUrl));
and XML:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference android:key="testRestUrl"
android:title="REST service URI"
android:defaultValue="R.string.testRestUrl">
</EditTextPreference>
</PreferenceScreen>

PreferenceActivity display/edit the values of a domain object

Given this code, how do I get the values from the checkbox- and textpreference and store them in the domain object?
public class MonitorPreferences extends PreferenceActivity {
private PersistenceManager pm;
private Monitor monitor;
private boolean mActive;
private String mName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pm = new PersistenceManager(getApplicationContext());
addPreferencesFromResource(R.xml.monitors_pref);
fetchDomainObject();
}
private void fetchDomainObject() {
monitor = pm.fetchMonitor(getIntent().getLongExtra(SuperListActivity.EXTRA_KEY_MONITOR_ID, -1));
}
private void persistDomainObject(Monitor monitor) {
pm.persist(monitor);
}
}
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="General">
<CheckBoxPreference
android:key="active_chkbox"
android:title="Active"
android:defaultValue="true"
android:persistent="false"/>
<EditTextPreference
android:key="name_txt"
android:dependency="active_chkbox"
android:title="Name"
android:summary="Enter a name"
android:dialogTitle="Enter a name"
android:dialogMessage="Enter a name"
android:defaultValue="John Doe"
android:persistent="false"/>
</PreferenceCategory>
</PreferenceScreen>
Original question: Creating a normal Activity with the look and feel of a PreferenceActivity
My goal is to edit the variables of a domain object from an Activity with the look and feel of stock android preferences. What's the easiest way of accomplishing this?
Would it be possible to create a a PreferenceActivity and somehow modify it to display/edit the values of a domain object instead of the values from SharedPreferences?
Of course. Just add the code to store the values into the database and don't forget to mension android:persistent=false attribute in your preferences xml.
final CheckBoxPreference soundcb = (CheckBoxPreference) findPreference("active_chkbox");
Further you can do many things with soundcb object: read the value, set onClickListeners and so on.

How do I get preferences to work in Android?

I've really been struggling through this. New to Java/Android. I'm writing my first app and this is the first thing that has taken me longer than a couple days of searching to figure out. Here's the setup: It's a BAC calculator / drink counter:
A formula is used to calculate the BAC. Here's the forumla:
Bac = ((StandardDrinks / 2) * (GenderConstant / Weight)) - (0.017 * Hours);
So as you can see, being able to modify the gender and weight will produce more accurate and personalized results. So I have them as doubles:
double GenderConstant = 7.5; //9 for female
double Weight = 180;
To change these variables I would like the person to be able to go into the settings and choose different values. I have these things set up, but not linked to the variables shown above because I cannot for the life of me figure out how. Here they are:
I press the menu button and this pops up. Great. I'll click Settings.
Now the preferences pops up. Here is my preferences.xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Personal Settings">
<ListPreference
android:title="Gender"
android:summary="Verify or deny the presence of a Y chromosome."
android:key="genderPref"
android:defaultValue="male"
android:entries="#array/genderArray"
android:entryValues="#array/genderValues" />
<ListPreference
android:title="Weight"
android:summary="How much the planet pulls on you, in pounds."
android:key="weightPref"
android:defaultValue="180"
android:entries="#array/weightArray"
android:entryValues="#array/weightValues" />
</PreferenceCategory>
<PreferenceCategory android:title="Drink Settings">
<ListPreference
android:title="Beer Size"
android:summary="The volume of your beer, in ounces."
android:key="beerPref"
android:defaultValue="12"
android:entries="#array/beerArray"
android:entryValues="#array/beerValues" />
<ListPreference
android:title="Shot Size"
android:summary="The volume of your shot, in ounces."
android:key="shotPref"
android:defaultValue="1.5"
android:entries="#array/shotArray"
android:entryValues="#array/shotValues" />
<ListPreference
android:title="Wine Size"
android:summary="The volume of your wine, in ounces."
android:key="winePref"
android:defaultValue="5"
android:entries="#array/wineArray"
android:entryValues="#array/wineValues" />
</PreferenceCategory>
</PreferenceScreen>
Onward to the weight ListPreference:
And that shows up. The values are stored as string-arrays in res/values/arrays.xml. Here's a sample, of just the weight ones:
<string-array name="weightArray">
<item>120 lbs</item>
<item>150 lbs</item>
<item>180 lbs</item>
<item>210 lbs</item>
<item>240 lbs</item>
<item>270 lbs</item>
</string-array>
<string-array name="weightValues">
<item>120</item>
<item>150</item>
<item>180</item>
<item>210</item>
<item>240</item>
<item>270</item>
</string-array>
This is basically as far as I've gotten. I can click a value, sure, but it doesn't change the formula because it's not linked with the doubles I created in DrinkingBuddy.java. All of the stuff displayed in the settings are just empty shells for now, including the spinner on the main layout (the default time is just set to 1 hour)
I did create a Preferences.java and have tried implementing various combinations of code found in tutorials and resources around the web, but to no avail. Here it is anyway, filled with failed attempts to make beerPref (the settings option to change how many ounces in the beer) correlate with a variable in my main class:
package com.dantoth.drinkingbuddy;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.Preference.OnPreferenceClickListener;
public class Preferences extends PreferenceActivity {
public static final String PREF_BEER_SIZE = "PREF_BEER_SIZE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
//Get the custom preference
Preference beerPref = (Preference) findPreference("beerPref");
beerPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
SharedPreferences customSharedPreference = getSharedPreferences("myCustomSharedPrefs", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = customSharedPreference.edit();
editor.commit();
return true;
}}
);}
}
A full on tutorial and sample code would be AWESOME as I've yet to find any reliable guides out there.
I'm still working all this out myself, but (somewhat adapted from my version) I think your Preferences class only needs to do the following:
public class Preferences extends PreferenceActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// load the XML preferences file
addPreferencesFromResource(R.xml.preferences);
}
}
Then in your main class, you can refer to the preferences:
public class DrinkingBuddy extends Activity
implements OnSharedPreferenceChangeListener {
private int weight;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
// register preference change listener
prefs.registerOnSharedPreferenceChangeListener(this);
// and set remembered preferences
weight = Integer.parseInt((prefs.getString("weightPref", "120")));
// etc
}
// handle updates to preferences
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (key.equals("weightValues")) {
weight = Integer.parseInt((prefs.getString("weightPref", "120")));
}
// etc
}
}
The saving of preference updates is handled for you.
(Not too sure about public/private declarations!)
You are requesting probably two different set of preference files.
Make sure you store the ListPreference values in the same files.
Start up adb roll to the cd /data/data/com.your.package and look for folders and files of type preferences.
I think the bug is that you specify a different file than the one the setting has been saved too:
Try changing this:
SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
to
SharedPreferences preferences = PreferenceManager
.getDefaultSharedPreferences(context);
Then you will probably have to query only
preferences.getString('weightPref', null);
Also you do not need the Editor. The preferences are saved automatically.
For most apps, it is most convinient to use the default shared preferences. You can get from anywhere in you app them with:
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
You can save new variables into it with:
sp.edit().putString("var_name", "var value".apply();

Categories

Resources