如何使用v7 / v14首选项支持库?

与M版本一起,还有新的支持库。 其中一个似乎非常有用的是v7首选项支持库。

它似乎没有PreferenceActivity或类似的东西,我们如何将其整合到我们的应用程序?

您必须扩展片段所需的AppCompatActivity ,并包含PreferenceFragmentCompat的子类。 抽象片段需要重写一个方法,在这个方法中,您应该放置您的偏好通货膨胀逻辑。 最后,你的活动主题需要指定一个preferenceTheme属性。

阅读这里的公告。 使用preference-v7库,您可以使用PreferenceFragmentCompat子类replacePreferenceFragment (API 11+),并使用SwitchPreferencereplaceSwitchPreference (API 14+),并使您的设置屏幕在API 7中工作。

以下是我如何使其工作:

SettingsActivity.java

 public class SettingsActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_settings); } } 

布局/ activity_settings.xml

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <fragment android:name=".SettingsFragment" android:tag=".SettingsFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout> 

SettingsFragment.java

 public class SettingsFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle bundle, String s) { addPreferencesFromResource(R.xml.preferences); } } 

XML /的preferences.xml

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.preference.PreferenceCategory ...> <android.support.v7.preference.ListPreference ... /> <android.support.v7.preference.SwitchPreferenceCompat ... /> ... </android.support.v7.preference.PreferenceCategory> ... </android.support.v7.preference.PreferenceScreen> 

价值观/ styles.xml

 <style name="AppTheme" parent="Theme.AppCompat.NoActionBar"> <item name="preferenceTheme">@style/PreferenceThemeOverlay</item> ... </style> 

preference-v7默认主题

 <style name="PreferenceThemeOverlay"> <item name="preferenceScreenStyle">@style/Preference.PreferenceScreen</item> <item name="preferenceFragmentStyle">@style/PreferenceFragment</item> <item name="preferenceCategoryStyle">@style/Preference.Category</item> <item name="preferenceStyle">@style/Preference</item> <item name="preferenceInformationStyle">@style/Preference.Information</item> <item name="checkBoxPreferenceStyle">@style/Preference.CheckBoxPreference</item> <item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat</item> <item name="dialogPreferenceStyle">@style/Preference.DialogPreference</item> <item name="editTextPreferenceStyle">@style/Preference.DialogPreference.EditTextPreference</item> <item name="preferenceFragmentListStyle">@style/PreferenceFragmentList</item> </style> 

使用新的首选项支持库v7,您可以将PreferenceFragmentCompat与任何ActivityAppCompatActivity

 public static class PrefsFragment extends PreferenceFragmentCompat { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preferences); } } 

你必须在你的主题中设置preferenceTheme

 <style name="AppTheme" parent="@style/Theme.AppCompat.Light"> ... <item name="preferenceTheme">@style/PreferenceThemeOverlay</item> </style> 

通过这种方式,您可以自定义preferenceTheme以便在不影响活动的其他部分的情况下对每个首选项types使用的布局进行样式设置。

hidro的回答是正确的,但是还有一件事要注意:

只需使用普通偏好xml标签,如PreferenceScreen而不是完整的类名称。 支持库将自动转换它们。

原因:如果使用完整的类名称,代码build议和布局预览将无法正常工作。

所以你应该写这样的XML:

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

你是对的,它并不存在于appcompat v7中,但是Google实际上增加了AppCompatDelegate抽象类作为委托,你可以使用它来将AppCompat的支持注入到任何活动中。 你可以从这个答案中find更多。

这是一个如何从AppCompat的Google示例中将AppCompatDelegate注入到您的活动中的示例,您可以在这里find它。

我试图实现Hidro的答案上面的一个活动,其中也包含一个工具栏,它给了我下面的布局通货膨胀exception,因为以下错误:

引起:java.lang.NullPointerException:试图调用虚拟方法'android.content.Context android.support.v4.app.FragmentHostCallback.getContext()'的空对象引用

我还没有能够解决这些问题,所以采取了以下措施:

 public class SettingsActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(savedInstanceState == null) getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new SettingsFragment()).commit(); } } 

使用SettingsActivity的以下布局:

 <?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"> <include layout="@layout/toolbar"/> <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </android.support.design.widget.CoordinatorLayout> 

在这里发布,因为如果其他人遇到相同的exception,它可能会有帮助

Interesting Posts