In my app I have a PreferenceScreen which looks like this:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<CheckBoxPreference
android:key="state"
android:title="#string/stateTitle"
android:summary="#string/stateSummary"
android:defaultValue="false" />
<Preference
android:key="test"
android:layout="#layout/pref_control"
android:dependency="state" />
</PreferenceScreen>
Now my question is how can I get the views which are in my pref_control.xml from the PreferenceActivity? I tried with normal findViewById() but that ends in a NullPointerException. Here is my code that causes the exception:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
((Button) findViewById(R.id.startTime)).setText("bla");
((Button) findViewById(R.id.endTime)).setText("bla");
}
You can get the Preference by using Preference p = findPrefences("test") from the Activity (or better the PreferenceFragment, if you are using newer versions of Android).
On that object you can call .getView(convertView, parent). For your purposes, it should be ok to call that method with null as paramters: findPreferences("test").getView(null, null).
HTH
Since you're using PreferenceActivity, you can use:
final CheckBoxPreference stateCheckBox = (CheckBoxPreference)findPreference("state");
and presumably:
final Preference testPreference = (Preference)findPreference("test");
It's deprecated but it should work.
Related
I'm using a PreferenceFragment and want the version of my app to appear below the List that holds all the settings. I know for a normal ListView I could just do addFooterView(theTextView), but the PreferenceFragment doesn't provide access to doing this (no access to the ListView that is populated from preferences xml). Anyone have a slick way of doing this?
George's answer (Option 1) was on the right track, but I found it better to take it one step further than simply adding a preference. I created a custom preference by using the layout in the accepted answer here, and then was able to totally customize what I wanted to show by centering text, and even making the preference only appear under certain circumstances (for example, if the user has the most recent version, don't show the preference, etc.).
I used the Android docs on Settings to create a class that extends Preference to do the dynamic work needed.
You can add an empty preference item in the end of xml, then give it an custom layout.
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- other preferences -->
<Preference app:layout="#layout/place_holder" />
</PreferenceScreen>
In your PreferencesFragment, just new a custom PreferenceCategory, then add it to PreferenceScreen. you can do your things in the onCreateView part of the custom PreferenceCategory.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
initPrefs();
PreferenceCategory preferenceCategory = new PreferenceCategory(getActivity()) {
#Override
protected View onCreateView(ViewGroup parent) {
super.onCreateView(parent);
View view =
getActivity().getLayoutInflater().inflate(R.layout.layout_infos, null);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "thanks", Toast.LENGTH_SHORT).show();
}
});
return view;
}
};
getPreferenceScreen().addPreference(preferenceCategory);
}
In my preferences UI, I need to hide a preference based on certain conditions.
public class MyFragment extends PreferenceFragment {
public void onCreate(Bundle state) {
addPreferencesFromResource(...);
ListPreference myList = (ListPreference) findPreference("myid");
...
if (condition) {
// hide myList
}
}
}
I cannot seem to find any method either on ListPreference or on PreferenceFragment to hide it from being shown in the UI. Would appreciate if you can point me in the right direction.
After much debugging, turns out it was quite simple. Here is what you need to do:
First, obtain the PreferenceCategory the item belongs to. Next, just call removePreference on it.
PreferenceCategory myCategory = (PreferenceCategory) findPreference("myPrefCategory");
myCategory.removePreference(myList);
For those wondering how to remove item that has no parent category - you should name your root like this:
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="root_preferences">
<PreferenceCategory
android:title="Developer tools"
android:key="dev_tools_category">
Then for example:
if (!BuildConfig.DEBUG) {
PreferenceScreen rootPreferences = (PreferenceScreen) findPreference("root_preferences");
PreferenceCategory devCategory = (PreferenceCategory) findPreference("dev_tools_category");
rootPreferences.removePreference(devCategory);
}
In example above "dev_tools_category" could be any preference widget or like I showed - a category.
You can just use the inherited methods from the Preference superclass.
myList.setShouldDisableView(true);
myList.setEnabled(false);
The first will make the backing view of the preference disappear when the preference is disabled, the second will actually disable the preference.
How can I change the view of a CheckBoxPreference at runtime?
Specifically, I'd like to change a CheckBoxPreference summary depending on whether the user has checked the box or not.
If it were a normal view, I could do something like:
view1 = (TextView)findViewById(R.id.idView1);
view1.setText("some text");
But a CheckBoxPreference has no id, so I don't know how to get a "handle" to it.
I have an answer to my own question. The key is to use findPreference in a PreferenceActivity, as follows:
public class MyPreferenceActivity extends PreferenceActivity{
private SharedPreferences preferences;
private SharedPreferences.OnSharedPreferenceChangeListener prefListener;
private CheckBoxPreference pref;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
pref = (CheckBoxPreference) findPreference(res.getString(R.string.keyAccount));
pref.setSummary("something");
//-- preference change listener
prefListener = new SharedPreferences.OnSharedPreferenceChangeListener(){
public void onSharedPreferenceChanged(SharedPreferences prefs, String key){
if (key.equals(somekey)){
pref.setSummary("something new");
}
}
};
preferences.registerOnSharedPreferenceChangeListener(prefListener);
}
This is tested and works.
You should use (in XML layout file):
android:summaryOff
android:summaryOn
You can set id to CheckBoxPreference using android:id in xml like code below
<CheckBoxPreference
android:key="pref_boot_startup"
android:title="Auto start"
android:defaultValue="true"
android:id="#+id/my_CheckBoxPref"
/>
To retrieve you can use
CheckBoxPreference check = (CheckBoxPreference)findViewById(R.id.my_CheckBoxPref);
I've got a preferences.xml stored in my res/xml folder:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory>
<Preference android:key="units_length" android:title="imperial"></Preference>
</PreferenceCategory>
</PreferenceScreen>
Here is how the onCreate method looks like in my activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.results);
// Get preferences
SharedPreferences preferences = getSharedPreferences("preferences", 0);
// Fetch the text view
TextView text = (TextView) findViewById(R.id.textView1);
// Set new text
text.setText(preferences.getString("units_length", "nothing"));
}
My application just says "nothing". What am I doing wrong here?
Try setting android:defaultValue attribute in your preference xml definition to whatever appropriate. It seems that property have never been initialized.
In my PreferenceActivity I have some Preferences.
One I inflate from layout:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.settings);
...
}
protected void onResume() {
super.onResume();
Preference registrationStatus = (Preference) findPreference("registrationStatusPref");
if (!TextUtils.isEmpty(somestring){
registrationStatus.setLayoutResource(R.layout.push_reg_status);
TextView push_reg_status_txt = (TextView)findViewById(R.id.pushRegTxtPref);
}
....
}
push_reg_status_txt is a TextView from push_reg_status layout, and push_reg_status_txt is always null.
push_reg_status layout:
....
<TextView
android:id="#+id/pushRegTxtPref"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:layout_marginBottom="4dp"
android:text="Registration Succesful"
android:textColor="#99ff33"
android:gravity="center_horizontal"
android:layout_gravity="center_horizontal"/>
.....
Why?
Preference.setLayoutResource() only updates the internal reference that preference has to a layout ID, it does not actually update the layout to redisplay. Therefore the TextView you are looking for with findViewById() is not inflated for your use. The only place Preferences inflate their layouts is when created.
You'll either need to have that custom layout set at the start (before addPreferencesFromResource() inflates everything), or adjust the title/summary properties of the existing preference instead to set your "Registration Successful" string. Also, if you are using a custom preference layout, make sure you're following the rules set forth in the SDK Documentation.
Hope that Helps!
Maybe because you calls findViewById of your Activity instead of calling same method of registrationStatus object.