2015-05-22 9 views
6

Ich habe in meiner Android App eine SettingsActivity. Ursprünglich gab es keine ActionBar, so dass ich implemted dies:Android verschachtelte PreferenceScreen mit 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(); 
      } 
     }); 
    } 
} 

Es funktioniert super, aber nur für die erste PreferenceScreen. Wenn ich einen verschachtelten PreferenceScreen habe, dann gibt es keine ActionBar. Wie kann ich dies erreichen, um auf dem verschachtelten PreferenceScreen eine ActionBar mit Backbutton zu haben?

Es sollte mit API15 + und AppCombat

Original-Beitrag kompatibel sein: How to add Action Bar from support library into PreferenceActivity?

+0

Haben Sie schon eine Lösung gefunden? –

+0

Nein. Ich habe meine eigenen Fragmente mit einigen ListView und CheckBoxen ohne den PreferenceScreen erstellt. Und es funktioniert gut und sieht aus wie der PreferencesScreen ... Ich hätte das schon viel früher machen sollen, bevor ich versucht habe, den PreferenceScreen in Betrieb zu nehmen – Tobi

+1

http://stackoverflow.com/a/27455363/2247612 Diese Antwort hat eine perfekte Lösung für den Support Bibliothek – harishannam

Antwort

2

Anstelle der verschachtelten PreferenceScreen, können wir eine einfache klickbare Preference verwenden und es so funktioniert, wenn es sich um eine „verschachtelte Kopf war "; Dies wird die übliche ActionBar anzeigen, da es eine PreferenceActivity-Instanz startet und daher auch die Navigation im Single-/Dual-Bereich beibehalten wird. Hier ist ein vereinfachtes Beispiel-Code, der ActionBar zurück Navigationstaste Setup enthält:

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 
    } 
} 

Wichtige: Wenn Sie Proguard verwenden, denken Sie daran die folgende Regel hinzufügen, sonst isInvalidFragment() gibt false:

-keepnames class com.foo.MyPreferenceActivity$SubscreenFragment