I would like to be able launch a 2nd Preference screen from my PreferenceActivity. And in the 2nd Preference screen I'd like to use a predefined layout from xml. So, I have two questions:
How do I use an xml layout as the layout view of a Preference? How do I add this custom preference to a PreferenceActivity such that launched when tapped?
Thank you
*EDIT in response to alibi
I am trying to launch an activity from a preference screen, by declaring the activity to be launched in xml. This causes this exception:
04-01 19:04:37.962: ERROR/AndroidRuntime(8061): android.content.ActivityNotFoundException: Unable to find explicit activity class {com.me/CustomPrefScreen}; have you declared this activity in your AndroidManifest.xml?
*Another update. However, if I replace PrefrenceScreen in settings.xml with some extension of Preference, which overrides onClick() to launch CustomPrefScreen, then everything works fine.
Main preferences activity:
public class MyPreferences extends PreferenceActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
}
settings.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen
android:summary="my summary"
android:title="my title">
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.me"
android:targetClass="CustomPrefScreen"/>
</PreferenceScreen>
</PreferenceScreen>
mainfest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.me"
android:versionCode="1"
android:versionName="1.0">
<application
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@style/Theme.NoBackground">
<activity
android:name=".MyApp"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".CustomPrefScreen"
android:label="@string/app_name">
</activity>
<activity
android:name=".MyPreferences"
android:label="@string/app_name">
</activity>
</application>
<uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
Use PreferenceFragmentCompat to programatically handle preferences. To load the settings into the fragment, load the preferences in the onCreatePreferences() method. To get an instance of a preference, search for a preference using its key through the PreferenceManager within onCreateView() .
From the menu bar, click File > Settings (on macOS, click Android Studio > Preferences).
A PreferenceFragmentCompat is the entry point to using the Preference library. This Fragment displays a hierarchy of Preference objects to the user. It also handles persisting values to the device. To retrieve an instance of android.
One solution would be to extend a DialogPreference which allows the setting of a custom layout for the preference dialog. This way you have a preference listed and when you tap it, you get a dialog with your custom settings UI.
<com.xyz.MyPreference
android:dialogLayout="@layout/yourlayout"
android:dialogTitle="Dialog Title"
android:dialogMessage="Dialog summary"
android:key="preference_key"
android:title="Preference Title"
android:summary="Preference summary"
android:defaultValue="Default Value" />
And the class
class MyPreference extends DialogPreference {
// along with constructors, you will want to override
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
// view is your layout expanded and added to the dialog
// find and hang on to your views here, add click listeners etc
// basically things you would do in onCreate
mTextView = (TextView)view.findViewById(R.Id.mytextview);
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult) {
// deal with persisting your values here
}
}
}
Obviously there are some other details, but this is the basic idea.
alibi's solution - of defining an intent within a <PreferenceScreen>
entry - worked for me, after much trial-and-error of the targetPackage
and targetClass
fields.
targetPackage
needs to be the full path to the package name of my application (that is, the package=
entry in the AndroidManifest.xml file). targetClass
needs to be the full path to the Activity - INCLUDING the package name, even if the Activity is in the same package as the Application.
The AndroidManifest.xml file for the Application also (of course) needs an entry for the Activity. I didn't define an <intent-filter>
for this entry, presumably because the action
is MAIN
(this was true whether the Activity was in the same or a different package than the Application).
Example: the Application's package is com.thissocialworld
. The Activity I'd like to kick off from the PreferencesScreen
is in a package called com.coolcommon
and the Activity class is com.thissocialworld.SpecialPreferences
. The entry within the <PreferenceScreen>
looks like this:
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.thissocialworld"
android:targetClass="com.thissocialworld.SpecialPreferences"/>
I may try changing action.MAIN
to action.PREFERENCES
if it seems to be necessary to get access to the PreferencesManager
.
(PS my first post here, I couldn't figure out how to post this as a comment to the discussion started by alibi.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With