2015-05-22 15 views
6

Ho nella mia app Android un SettingsActivity. In origine non c'era ActionBar, così ho implemted questo:Android nested PreferenceScreen con ActionBar

settings_toolbar.xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v7.widget.Toolbar 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/toolbar" 
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:minHeight="?attr/actionBarSize" 
    app:navigationContentDescription="@string/abc_action_bar_up_description" 
    android:background="?attr/colorPrimary" 
    app:navigationIcon="?attr/homeAsUpIndicator" 
    app:title="@string/action_settings" 
    /> 

SettingsActivity.java

public class SettingsActivity extends PreferenceActivity { 

    @Override 
    protected void onPostCreate(Bundle savedInstanceState) { 
     super.onPostCreate(savedInstanceState); 

     LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent(); 
     Toolbar bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); 
     root.addView(bar, 0); // insert at top 
     bar.setNavigationOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       finish(); 
      } 
     }); 
    } 
} 

E le grandi opere, ma solo per il primo PREFERENCE. Se ho un PreferenceScreen annidato, non ci sono ActionBar. Come posso ottenere questo, per avere sul PreferenceScreen annidato un ActionBar con pulsante indietro anche tu?

Dovrebbe essere compatibile con API15 + e AppCombat

Original post: How to add Action Bar from support library into PreferenceActivity?

+0

Avete già trovato una soluzione? –

+0

No. Ho creato i miei frammenti con alcuni ListView e CheckBox, senza PreferenceScreen. Funziona alla grande e sembra il PreferencesScreen ... avrei dovuto farlo molto prima che provassi a far funzionare il PreferenceScreen – Tobi

+1

http://stackoverflow.com/a/27455363/2247612 Questa risposta ha una soluzione perfetta per il supporto Biblioteca – harishannam

risposta

2

Invece di usare il PREFERENCE annidati, possiamo usare una semplice preferenza cliccabile e farlo funzionare come se fosse un "Header annidato "; questo mostrerà il solito ActionBar poiché avvia un'istanza PreferenceActivity e pertanto manterrà anche lo stile di navigazione a pannello singolo/doppio. Ecco qualche esempio di codice semplificato, che comprende l'installazione di nuovo tasto di navigazione del ActionBar:

main_preferences.xml

<PreferenceScreen 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:orderingFromXml="true"> 
    <Preference  
    android:key="a_preference" /> 

    <!-- this is our "nested header", a simple Preference --> 
    <Preference 
    android:key="subscreen_preference" /> 

    <Preference  
    android:key="another_ preference" /> 

</PreferenceSreen> 

subscreen_preference.xml

<PreferenceScreen 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:orderingFromXml="true"> 
    <Preference  
    android:key="sub_preference" /> 

    <!-- etc --> 

</PreferenceSreen> 

MyPreferenceActivity.class

public class MyPreferenceActivity extends AppCompatPreferenceActivity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     //display back button. Fragments will handle its behavior (see below) 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
} 

@Override 
public void onBuildHeaders(List<Header> target) { 
    loadHeadersFromResource(R.xml.pref_headers, target); 
} 

@Override 
protected boolean isValidFragment(String fragmentName) { 
    return MainPreferenceFragment.class.getName().equals(fragmentName) || 
      SubscreenFragment.class.getName().equals(fragmentName); 
} 


public static class MainPreferenceFragment extends PreferenceFragment { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 

     //let the fragment intercept the ActionBar buttons: 
     setHasOptionsMenu(true); 

     addPreferencesFromResource(R.xml.main_preferences); 

     findPreference("subscreen_preference").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { 

      @Override 
      public boolean onPreferenceClick(Preference preference) { 
       //we create a Header manually: 
       Header header = new Header(); 
       //mandatory fragment name: 
       header.fragment = "com.foo.MyPreferenceActivity$SubscreenFragment"; 
       //subscreen title to be shown in the ActionBar 
       header.titleRes = R.string.settings_fragment_title; 
       //this will do the trick, no further action required: 
       //we can ignore the second parameter 
       ((MyPreferenceActivity)getActivity()).onHeaderClick(header, 0); 
       return true; 
      } 
     }); 
    } 

    //this will make the ActionBar back navigation button 
    // behave like the system back button 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     int id = item.getItemId(); 
     if (id == android.R.id.home) { 
      if (!super.onOptionsItemSelected(item)) { 
       getActivity().onBackPressed(); 
      } 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 
} 

public static class SubscreenFragment extends PreferenceFragment { 
    //usual implementation 
    } 
} 

Importante: se si utilizza Proguard, ricordarsi di aggiungere la seguente regola, altrimenti isInvalidFragment() restituirà falso:

-keepnames class com.foo.MyPreferenceActivity$SubscreenFragment 
Problemi correlati