16

versteckt Ich verwende in ActionBarActivity von support-v7-Bibliothek.
In der Aktivität habe ich Toolbar. Alles geht gut, bis ich ein verschachteltes PreferenceScreen öffne. Im geöffneten Bildschirm ist die Toolbar versteckt.Symbolleiste ist in verschachtelten PreferenceScreen

Vielleicht kennt jemand einen Workaround für dieses Problem?

Einstellungen xml-Datei:

<?xml version="1.0" encoding="utf-8"?> 
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > 

    <PreferenceCategory android:title="Main category" > 

     <EditTextPreference 
      android:defaultValue="defaultValue" 
      android:key="key_global_setting" 
      android:title="Global title" />   

    </PreferenceCategory> 

    <PreferenceCategory android:title="Nested screens" >   

     <PreferenceScreen 
      android:persistent="false" 
      android:title="@string/settings_facility_title" > 

     <CheckBoxPreference 
      android:defaultValue="false" 
      android:key="nested_screen_1_1" 
      android:title="Nested screen 1.1 check box" /> 

     <CheckBoxPreference 
      android:defaultValue="true" 
      android:key="nested_screen_1_2" 
      android:title="Nested screen 1.2 check box" /> 
     </PreferenceScreen> 

     <PreferenceScreen 
      android:persistent="false" 
      android:title="@string/settings_menu_screen_title" > 

     <CheckBoxPreference 
      android:defaultValue="true" 
      android:key="nested_screen2" 
      android:title="Nested screen 2 check box" /> 
     </PreferenceScreen>   

    </PreferenceCategory>  

</PreferenceScreen> 

Aktivität Layout:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    tools:context=".SettingsScreen" > 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     style="@style/Toolbar" /> 

    <FrameLayout 
     android:id="@+id/contentSettings" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

</LinearLayout> 
+0

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

Antwort

26

ich die Lösung auf meinem eigenen gefunden. Ich habe einen kleinen Work-Around von diesem verschachtelten PreferenceScreen's verwendet. Ich habe einfach eine Trennung zu verschiedenen xml-preference Dateien gemacht, erstellt eine zusätzliche Fragment, die PreferenceFragment erweitert und dort zeige ich eine entsprechende geschachtelte Einstellung Bildschirm.
Vielleicht würde jemand das nützlich finden.

Github sources link.

Einige Codebeispiele unter:

main_preferences.xml

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > 

    <PreferenceCategory android:title="Main category" > 

     <EditTextPreference 
      android:defaultValue="defaultValue" 
      android:key="key_global_setting" 
      android:title="Global title" /> 

    </PreferenceCategory> 

    <PreferenceCategory android:title="Nested screens" > 

     <Preference 
      android:key="NESTED_KEY1" 
      android:persistent="false" 
      android:title="Nested screen #1" /> 

     <Preference 
      android:key="NESTED_KEY2" 
      android:persistent="false" 
      android:title="Nested screen #2" /> 

    </PreferenceCategory> 

</PreferenceScreen> 

nested_screen1_preferences.xml

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" 
    android:title="Nested screen #1" > 

    <CheckBoxPreference 
     android:defaultValue="false" 
     android:key="nested_screen_1_1" 
     android:title="Nested screen 1.1 check box" /> 

    <CheckBoxPreference 
     android:defaultValue="true" 
     android:key="nested_screen_1_2" 
     android:title="Nested screen 1.2 check box" /> 
</PreferenceScreen> 

nested_screen2_preferences.xml

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" 
    android:title="Nested screen #2"> 

    <CheckBoxPreference 
     android:defaultValue="true" 
     android:key="nested_screen2" 
     android:title="Nested screen 2 check box" /> 
</PreferenceScreen> 

SettingsActivity.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); 
    } 
} 

NestedPreferencesFragment.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; 
     } 
    } 

} 
+0

Ich war vor kurzem in dieser Frage zu prüfen. Deine Lösung ist nett, aber du kannst nur 1 Verschachtelungsebene verwenden, richtig?Irgendwelche Ideen, diese zu erweitern, um beliebig viele verschachtelte Einstellungsseiten zu verwenden? Ich habe einen Workaround gesehen, indem ich die Toolbar als eine benutzerdefinierte Einstellung gemacht habe, die funktioniert, aber es scheint mir sehr hacky zu sein. –

+0

Ja, mit der aktuellen Lösung können Sie nur eine Verschachtelungsebene haben. Jedenfalls basiert meine Lösung auf der Manipulation mit dem Back-Stack des Fragments. Ich denke, es ist sehr gut möglich, dem aktuellen Backstack zusätzliche Fragmente hinzuzufügen und die Logik so zu betreiben, dass beliebig viele verschachtelte Prefs erstellt werden können. – yurezcv

+0

Danke Bruder! Ausgezeichnete Antwort. –

6

kommt meine Lösung, die durch die ursprüngliche Antwort inspiriert ist, aber nicht so kompliziert. Vielleicht hilft es jemandem ...

layout/settings.xml:

<RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" > 

     <include 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_alignParentTop="true" 
      layout="@layout/toolbar" /> 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:id="@+id/content" 
      android:layout_below="@+id/toolbar"/> 

    </RelativeLayout> 

Klassen:

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 <Preference android:key="nested" android:persistent="false"/>` 
    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 { 
    ... 
} 

Getestet habe ich es auf 4.3 und 5.0.2 und keine Beschränkung auf Schachtelungsebenen gilt

0

In meiner Lösung, die Sie brauchen nur eine AppCompatActivity und ein PreferenceFragement, aber mehrere XML-Dateien mit jeweils nur einer Ebene von PreferenceScreens.

XML-Dateiliste

  • Top-Level-PreferenceScreen
  • zweite Ebene PreferenceScreen 0
  • zweite Ebene PreferenceScreen 1
  • zweite Ebene PreferenceScreen 2
  • ...

Dieser Code ist für eine Unterebene gedacht (der Einfachheit halber und um die Idee zu verstehen), aber Sie können ihn leicht auf beliebige Unterebenen von erweitern.

SettingsFragment.java

public class SettingsFragment extends PreferenceFragment 
{ 
    private int xmlId; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     xmlId = R.xml.preferences; 
     addPreferencesFromResource(xmlId); 
    } 

    public void changePrefScreen(int xmlId, int titleId) 
    { 
     this.xmlId = xmlId; 
     ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(getActivity().getResources().getString(titleId)); 
     getPreferenceScreen().removeAll(); 
     addPreferencesFromResource(xmlId); 
    } 

    // will be called by SettingsActivity (Host Activity) 
    public void onUpButton() 
    { 
     if(xmlId == R.xml.preferences) // in top-level 
     { 
      // Switch to MainActivity 
      Intent intent = new Intent(getActivity(), MainActivity.class); 
      startActivity(intent); 
     } 
     else // in sub-level 
     { 
      changePrefScreen(R.xml.preferences, R.string.settings); 
     } 
    } 

    @Override 
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) 
    { 
     String key = preference.getKey(); 

     // 
     // Top level PreferenceScreen 
     // 
     if(key.equals("top_key_0")) 
     { 
      changePrefScreen(R.xml.download_preference_screen, R.string.download_database); // descend into second level 
     } 

     // ... 

     // 
     // Second level PreferenceScreens 
     // 
     if (key.equals("second_level_key_0")) 
     { 
      // do something... 
     } 

     // ... 
    } 

SettingsActivity.java

public class SettingsActivity extends AppCompatActivity 
{ 
    SettingsFragment settingsFragment; 

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

     settingsFragment = new SettingsFragment(); 

     // Display the fragment as the main content. 
     getFragmentManager().beginTransaction() 
       .replace(android.R.id.content, settingsFragment) 
       .commit(); 
    } 

    // 
    // Handle what happens on up button 
    // 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) 
    { 
     switch (item.getItemId()) 
     { 
      case android.R.id.home: 
       settingsFragment.onUpButton(); 
       return true; 
     } 
     return true; 
    } 

    // ... 
} 

Technisch Verfügung der PreferenceFragment ist für alle Android-Versionen, für die funktionieren sollte.

0

Da die Ausgabe stammt aus dem Teil, den Sie immer noch in der gleichen Aktivität/Fragment und dem verschachtelten pref Bildschirm sind nur ein Dialog Sie folgendes tun:

  • Sie Präferenz klicken Zuhörer
  • einstellen
  • die Stammansicht aus dem Dialog Get: (PreferenceScreen)preference).getDialog().getWindow() .getDecorView().getRootView());

  • Recursively suchen, bis eine Stub-Ansicht finden (ist es eine, leider weiß ich nicht, die android.R.id.xxxxx) und stellen Sie, was Sie brauchen Layout als Titel, die wie die Symbolleiste aussehen wird (Sie können Ihre Symbolleiste aufblasen):

    private Toolbar toolbar; 
    
        public void findViewStub(ViewGroup viewGroup) { 
        int childCount = viewGroup.getChildCount(); 
        for (int i = 0; i < childCount; i++) { 
         View childView = viewGroup.getChildAt(i); 
         if(childView instanceof ViewStub){ 
          ((ViewStub)childView).setLayoutResource(R.layout.your_title_layout); 
          toolbar = ((ViewStub)childView).inflate(); 
         } 
         if (childView instanceof ViewGroup) { 
          findViewStub((ViewGroup) childView); 
         } 
        } 
    
        } 
    
    toolbar.setNavigationIcon(); 
    toolbar.setNavigationOnClickListener(); 
    toolbar.setTitle(); 
    
  • Im Layout können Sie nur eine Symbolleiste setzen können. Und setze das Zurück-Icon. Registrieren Sie sich, um darauf zu klicken und einen Verweis auf das Fragment zu haben. Beim Klicken können Sie den Dialog schließen. Sie haben festgelegt Titel usw.

Verwandte Themen