Ti suggeriamo di testare questa risoluzione in un ambiente controllato prima di spostarla in produzione, saluti.
Soluzione:
Ho trovato la soluzione da solo. Ho utilizzato un piccolo work-around di tutto questo annidato PreferenceScreen's
. Ho semplicemente fatto una separazione tra diversi xml-preference
e ho creato un ulteriore file Fragment
che estende PreferenceFragment
e lì mostro un'appropriata schermata di preferenze annidata.
Forse qualcuno lo troverà utile.
Link ai sorgenti di Github.
Alcuni esempi di codice qui sotto:
main_preferences.xml
nested_screen1_preferences.xml
nested_screen2_preferences.xml
ImpostazioniAttività.java
public class SettingsActivity extends ActionBarActivity implements MyPreferenceFragment.Callback {
private static final String TAG_NESTED = "TAG_NESTED";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.contentSettings, new MyPreferenceFragment())
.commit();
}
}
@Override
public void onBackPressed() {
// this if statement is necessary to navigate through nested and main fragments
if (getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
} else {
getFragmentManager().popBackStack();
}
}
@Override
public void onNestedPreferenceSelected(int key) {
getFragmentManager().beginTransaction().replace(R.id.contentSettings, NestedPreferenceFragment.newInstance(key), TAG_NESTED).addToBackStack(TAG_NESTED).commit();
}
}
MyPreferenceFragment.java
// The main preference fragment class
public class MyPreferenceFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener {
private Callback mCallback;
private static final String KEY_1 = "NESTED_KEY1";
private static final String KEY_2 = "NESTED_KEY2";
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof Callback) {
mCallback = (Callback) activity;
} else {
throw new IllegalStateException("Owner must implement Callback interface");
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.main_preferences);
// add listeners for non-default actions
Preference preference = findPreference(KEY_1);
preference.setOnPreferenceClickListener(this);
preference = findPreference(KEY_2);
preference.setOnPreferenceClickListener(this);
}
@Override
public boolean onPreferenceClick(Preference preference) {
// here you should use the same keys as you used in the xml-file
if (preference.getKey().equals(KEY_1)) {
mCallback.onNestedPreferenceSelected(NestedPreferenceFragment.NESTED_SCREEN_1_KEY);
}
if (preference.getKey().equals(KEY_2)) {
mCallback.onNestedPreferenceSelected(NestedPreferenceFragment.NESTED_SCREEN_2_KEY);
}
return false;
}
public interface Callback {
public void onNestedPreferenceSelected(int key);
}
}
FrammentoPreferenzeNidificate.java
public class NestedPreferenceFragment extends PreferenceFragment {
public static final int NESTED_SCREEN_1_KEY = 1;
public static final int NESTED_SCREEN_2_KEY = 2;
private static final String TAG_KEY = "NESTED_KEY";
public static NestedPreferenceFragment newInstance(int key) {
NestedPreferenceFragment fragment = new NestedPreferenceFragment();
// supply arguments to bundle.
Bundle args = new Bundle();
args.putInt(TAG_KEY, key);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkPreferenceResource();
}
private void checkPreferenceResource() {
int key = getArguments().getInt(TAG_KEY);
// Load the preferences from an XML resource
switch (key) {
case NESTED_SCREEN_1_KEY:
addPreferencesFromResource(R.xml.nested_screen1_preferences);
break;
case NESTED_SCREEN_2_KEY:
addPreferencesFromResource(R.xml.nested_screen2_preferences);
break;
default:
break;
}
}
}
Ecco la mia soluzione, che si ispira alla risposta originale ma non è così complicata. Forse può aiutare qualcuno...
layout/settings.xml
:
Classi:
public class SettingsActivity extends ActionBarActivity {
@Override
protected void onCreate( Bundle savedInstanceState ) {
setContentView( R.layout.settings );
super.onCreate( savedInstanceState );
initializeSupportActionBar();
getFragmentManager().beginTransaction().replace( R.id.content, new MainFragment() ).commit();
}
@Override
public void onBackPressed() {
if( !getFragmentManager().popBackStackImmediate() ) super.onBackPressed();
}
}
public class MainFragment extends PreferenceFragment {
public MainFragment() {}
@Override
public void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
addPreferencesFromResource( R.xml.pref_main );
// "nested" is the `
findPreference( "nested" ).setOnPreferenceClickListener( new OnPreferenceClickListener() {
@Override public boolean onPreferenceClick( Preference preference ) {
getFragmentManager().beginTransaction().replace( R.id.content, new NestedFragment() ).addToBackStack( NestedFragment.class.getSimpleName() ).commit();
return true;
}
} );
}
public class NestedFragment extends PreferenceFragment {
...
}
L'ho testato su 4.3
e 5.0.2
e non si applica alcuna limitazione ai livelli di annidamento
Ricorda che puoi optare per l'opzione per dire se ti ha aiutato.