Reputation: 1266
I want start a fragment on clicking a preference item. Refer below:
<PreferenceSreen
android:key="zd_pref"
android:summary="@string/zd_summary_no"
android:title="@string/zd_platform" >
<intent
android:action="com.example.prefs.PREFS_ONE"
android:targetClass="com.android.settings.bussiness.AuthCertifyConfirm"
android:targetPackage="com.example.settings" />
</PreferenceSreen>
<PreferenceSreen
android:key="hw_pref"
android:summary="@string/hw_summary"
android:title="@string/hw_platform" >
<intent
android:action="com.example.prefs.PREFS_ONE"
android:targetClass="com.android.settings.bussiness.AuthCertifyConfirm"
android:targetPackage="com.example.settings" />
</PreferenceSreen>
The AuthCertifyConfirm is a fragment,
public class AuthCertifyConfirm extends Fragment {}
BUT, this method caused error, when click the preference. The errors:
E/AndroidRuntime(28027): FATAL EXCEPTION: main
E/AndroidRuntime(28027): android.view.InflateException: Binary XML file line #21: Error inflating class PreferenceSreen
E/AndroidRuntime(28027): at android.preference.GenericInflater.createItemFromTag(GenericInflater.java:441)
E/AndroidRuntime(28027): at android.preference.GenericInflater.rInflate(GenericInflater.java:481)
E/AndroidRuntime(28027): at android.preference.GenericInflater.inflate(GenericInflater.java:326)
E/AndroidRuntime(28027): at android.preference.GenericInflater.inflate(GenericInflater.java:263)
E/AndroidRuntime(28027): at android.preference.PreferenceManager.inflateFromResource(PreferenceManager.java:269)
E/AndroidRuntime(28027): at android.preference.PreferenceFragment.addPreferencesFromResource(PreferenceFragment.java:285)
E/AndroidRuntime(28027): at com.android.settings.bussiness.BussinessSettings.onCreate(BussinessSettings.java:78)
E/AndroidRuntime(28027): at android.app.Fragment.performCreate(Fragment.java:1673)
E/AndroidRuntime(28027): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:854)
E/AndroidRuntime(28027): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)
E/AndroidRuntime(28027): at android.app.BackStackRecord.run(BackStackRecord.java:682)
E/AndroidRuntime(28027): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
E/AndroidRuntime(28027): at android.app.FragmentManagerImpl$1.run(FragmentManager.java:441)
E/AndroidRuntime(28027): at android.os.Handler.handleCallback(Handler.java:725)
E/AndroidRuntime(28027): at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(28027): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(28027): at android.app.ActivityThread.main(ActivityThread.java:5041)
E/AndroidRuntime(28027): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(28027): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(28027): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
E/AndroidRuntime(28027): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
E/AndroidRuntime(28027): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(28027): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.preference.PreferenceSreen" on path: /data/app/com.android.settings-1.apk
Why this method can't start a fragment?
Upvotes: 2
Views: 5279
Reputation: 155
If you've arrived here in 2021, chances are you are using Kotlin and Navigation Component.
So you can do the following:
In your settings.xml:
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<Preference
app:key="@string/fragment_settings_key"
app:title="Go to Fragment!"/>
</PreferenceScreen>
And in your SettingsFragment:
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.settings, rootKey)
val preferenceFragment: Preference? = findPreference(getString(R.string.fragment_settings_key))
preferenceFragment?.onPreferenceClickListener = Preference.OnPreferenceClickListener {
view?.findNavController()?.navigate(R.id.MyFragment)
true
}
}
}
Upvotes: 3
Reputation: 243
Intents are for starting activities, services, content providers and broadcast receivers. So if the fragment you want to add is in the same activity as the preference fragment it wouldn't be the ideal use case for an intent. Maybe try something of the sorts:
public class MyPreferenceFragment extends PreferenceFragmentCompat{
OpenFragmentListener openFragmentListener;
public interface OpenFragmentListener{
void openFragment();
}
@Override
public void onAttach(Activity activity){
super.onAttach(activity);
openFragmentListener = (OpenFragmentListener)activity;
}
@Override
public void onCreatePreferences(Bundle bundle, String s) {
getPreferenceManager().setSharedPreferencesName(Constants.PREFERENCES);
addPreferencesFromResource(R.xml.preferences);
preference = this.findPreference("key");
preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener(){
@Override
public boolean onPreferenceClick(Preference preference){
openFragmentListener.openFragment();
return true;
}
});
}
}
And then in the Activity implement MyPreferenceFragment.OpenFragmentListener and override the method something like this:
@Override
public void openFragment(){
getSupportFragmentManager()
.beginTransaction()
.remove(myPreferenceFragment)
.add(R.id.placeHolderForTheFragmentYouWant, theFragmentYouWant)
.addToBackStack("setting")
.commit();
}
Upvotes: 1