I have a class which extends from ListView. I added some extra functionality(drag and drop) for this new class. My question is there any way i can use this extended ListView class in a preference activity.
I need to provide drag and drop functionality for a legacy preference activity.
Are you asking if it's possible to open an arbitrary activity from a clicked item in a preference activity? If so, you need to do two things. First, add a PreferenceScreen item to your preferences xml file:
<PreferenceScreen
android:key="CUSTOM_ACTIVITY_KEY"
android:title="Title"
android:summary="Summary" />
Then in your settings activity's onCreate:
Preference pref = getPreferenceScreen().findPreference("CUSTOM_ACTIVITY_KEY");
final Intent intent = new Intent(this, CustomActivity.class);
if (pref != null)
{
pref.setOnPreferenceClickListener(new OnPreferenceClickListener()
{
public boolean onPreferenceClick(final Preference preference)
{
startActivity(intent);
return false;
}
});
}
If running a custom activity off of a PreferenceScreen item isn't enough, the only other option I could think of is to roll your own Preferences implementation. Someone else should correct me if I'm mistaken, but I think it might be possible to pull the Preferences source and modify accordingly.
I came across another API in
android.preference.PreferenceScreen.bind(ListView listView)
Binds a ListView to the preferences contained in this PreferenceScreen via getRootAdapter().
So after inflating the layout file, we will be able to attach the our custom listview to this the preferenceScreen of the activity.
Related
I have a main activity that loads a PreferenceFragment (its part of an actionBar).
Within the PreferenceFragment I load my preferences from a XML File:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
The Problem is if I change the Tab (remember it is getting managed by an ActionBar), change one of the preferences in a different fragment and coming back to my preferenceFragment its not getting updated. Particularly the problem is a SwitchPreference(true/false) which can be changed from different fragments and even by remote calls (then the preference is getting changed in shared preferences. YES I did commit the change).
I searched for different solutions, but to be honest I didn´t find a working one.
My own ideas are the following:
My Problem would be solved if I could get the Switch Element of the switch, so I could set the switch to true in the onStart() or onResume() method. But is there a change to get the Switch Object?
If I would load a usual layout I could access the switch like this:
View v = inflater.inflate(R.layout.start_fragment, container, false);
Switch status = (Switch) v.findViewById(R.id.switch1);
Afterwards I would be able to set the Position of the Switch like this:
status.setChecked(true);
Another solution would be to destroy the actual view and call addPreferencesFromResource() again, but to be honest I have no idea how this could be done....
The third solution could be to use a OnCheckedChangeListener in my PreferenceFragment, but the problem would again be how to change/update the switch.
I am sure that the Preference is updated correctly, because I´m running a OnSharedPreferenceChangeListener in one of my services and to debug this problem I made the listener log the status of my switchPreference.
Can you help me somehow?
unfortunately I cannot answer my own question before tomorrow morning, so I edit my question:
Thank you guys, I don´t want to restart the underlying activity, but only the fragment.
Fortunately I found a clue in this thread: How do you refresh PreferenceActivity to show changes in the settings?
I can really access the SwitchPreference that simple.
My solution is:
private SwitchPreference pref_phone_locked;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
status = (SwitchPreference) findPreference("status");
}
public void onStart(){
super.onStart();
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
if(sharedPref.getBoolean("status", false)){
status.setChecked(true);
}else{
status.setChecked(false);
}
}
This way I can simply cast the Preference to a SwitchPreference and modify it after every onStart() call. I guess this is the best solution for my problem.
Hopefully this answer will save someones time in future =)
Thanks you guys again!
I'm not sure if this will work for you ( I've a very basic knowlege of Android ) but I found this solution in a similar question and it works very well for me
private void simulateRefresh(){
Intent intent = getIntent();
overridePendingTransition(0, 0);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
overridePendingTransition(0, 0);
startActivity(intent);
}
Basically this destroy and recreate the activity without animation in between.
Found here
I've implemented my own PreferenceFragment subclass (detailed here), and want to listen for preference changes within it. PreferenceFragment provides you with two ways of doing this:
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
and
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
Which one should be used? What's the difference? I don't really understand the distinction made in the Android docs.
The core difference is in their names, PreferenceManger grants access to different functionalities to the developer for managing SharedPreferences, such as retrieving the map of current preference values or setting user preferences. to their default values. PreferenceScreen handles displaying a screen of user preferences, so that the user can assign values to them. Sometimes this means displaying a list item on a screen with other preferences, that opens another screen with more preferences when clicked, as is the case when PreferenceScreens are nested.
Your question implies that you think there is a difference between what PreferenceManager.getSharedPreferences() and PreferenceScreen.getSharedPreferences() does, but according to the source code, they are identical.
PreferenceScreen:
public SharedPreferences getSharedPreferences() {
if (mPreferenceManager == null) {
return null;
}
return mPreferenceManager.getSharedPreferences();
}
So the PreferenceManger and PreferenceScreen are different entities, but the SharedPreference those method return should be the same object, since PreferenceScreen calls the method from PreferenceManager. I hope that is the answer you've been seeking.
If you have a choice, go with PreferenceManager.getSharedPreferences(), it's more obvious and one fewer method call internally.
Fun fact:
PreferenceFragment:
public PreferenceManager getPreferenceManager() {
return mPreferenceManager;
}
public PreferenceScreen getPreferenceScreen() {
return mPreferenceManager.getPreferenceScreen();
}
The first one gets the shared preferences from the PreferenceManager. The second one, from the PreferenceScreen, that inherits this method from Preference class.
I think this is not a functional difference, because both return probably the same instance of the SharedPreferences objects, but I think it's clearer to use the first one (using PreferenceManager instead of PreferenceScreen).
PreferenceScreen see domentation here
PreferenceScreen class can appear in two places:
When a PreferenceActivity points to this, it is used as the root and
is not shown (only the contained preferences are shown).
When it appears inside another preference hierarchy, it is shown and
serves as the gateway to another screen of preferences (either by
showing another screen of preferences as a Dialog or via a
startActivity(android.content.Intent) from the getIntent()). The
children of this PreferenceScreen are NOT shown in the screen that
this PreferenceScreen is shown in. Instead, a separate screen will be
shown when this preference is clicked.
PreferenceManager see documentation here:
Difference :
getPreferenceManager () returns the current preference manager associated with the fragment.
getPreferenceScreen () returns the root PreferenceScreen i.e. root preference screen used in the fragment from preference xml file(preferences.xml).
Inside my Configuration activity i need to create a preference screen with a fixed View at the top showing a preview of content configured in the page. I don't want to change the main preference screen (i have already a separate activity for that) i want a different layout for a "nested" preferencescreen.
What i've tried is specifying an Intent inside the preference screen however when i click on this options nothing happens and activity goes into timeout... Activity is correctly configured on the manifest (and extends ConfigureActivity as the main one does).
<PreferenceScreen
android:key="inner"
android:title="Title"
android:summary="Summary"
>
<intent
android:action="android.appwidget.action.APPWIDGET_CONFIGURE"
android:targetPackage="my.package.lib"
android:targetClass="my.package.lib.ConfigureClass"
/>
</PreferenceScreen>
Another idea could be creating a custom "preference" that launches another configuration activity, could this work? Would be correct/acceptable to have multiple configuration activities?
The following code on the main ConfigureActivity works however i don't know if its a clean way to do what i want. Could someone confirm?
PreferenceScreen b = (PreferenceScreen) findPreference("my_empty_preference_screen");
b.setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent(ConfigureActivity.this, ConfigureActivity.class);
intent.setAction("android.appwidget.action.APPWIDGET_CONFIGURE");
ConfigureActivity.this.startActivity(intent);
return false;
}
});
I have a PreferenceScreen that is defined in XML that serves all the preferences for my application. This PreferenceScreen also has a child PreferenceScreen nested within it. My implementing class is called PreferencesActivity. I know I can open the main Preferences window via startActivity(new Intent(this, PreferencesActivity.class)); but how do I go about opening the child PreferenceScreen via an Intent?
i researched a while on this topic for my project Theft Aware (http://www.theftaware.com) (a little bit advertisement... :-) and i found the solution:
PreferenceScreen screen = getPreferenceScreen(); // gets the main preference screen
screen.onItemClick(null, null, INDEX , 0); // click on the item
where INDEX is the position of the item you want to open on the screen
see this question for a more general solution based on Reinhard's idea, finally!
My application has a setting menu which is actually a PreferenceActivity.
When it's created, if a boolean value is not set I want to go to the DialogPreference which sets that.
I tried doing it with an intent but the application force closed with this error msg:
E/AndroidRuntime( 239):
android.content.ActivityNotFoundException:
Unable to find explicit activity class
{com.xxxx/com.xxxx.xxxxPreference};
have you declared this activity in
your AndroidManifest.xml?
How should I do this? It's ok to add that DialogPreference to the manifest?
A DialogPreference isn't an Activity in its own right. It's just a Preference which displays a Dialog when clicked.
The problem is that there's no obvious way programmatically click a Preference. However, since you're using DialogPreference you've already got you own subclass of it. So we can solve our problem by adding the following method to your subclass of DialogPreference:
//Expose the protected onClick method
void show() {
onClick();
}
Then in the onCreate() of your PreferencesActivity you'll have something like this to load the preferences from your XML file:
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
After that you can put some code like this:
booleanProp = true; //set this to the value of the property you're checking
if (! booleanProp) {
//Find the Preference via its android:key
//MyDialogPreference is your subclasss of DialogPreference
MyDialogPreference dp = (MyDialogPreference)getPreferenceScreen().findPreference("dialog_preference");
dp.show();
}
This is a bit of hack, as exposing protected methods isn't ideal, but it does work.
Another option would be to replace the Dialog with a PrefenceActivity which contained all the options you wish to maintain and then you could launch it via an Intent, but I'm assuming there's a good reason that you want your own custom Dialog with a specific layout. If you do want a second PreferenceActivity you can add it to your preferences XML file as follows:
<PreferenceScreen
android:title="#string/title_of_preference"
android:summary="#string/summary_of_preference">
<intent android:action="your.action.goes.HERE"/>
</PreferenceScreen>
To start an activity with an Intent, the activity must be in the Android manifest. Just add a line like:
<activity android:name=".path.to.MyActivity"/>