我刚刚注意到一个事实,该方法在Android文档(参考条目)中已addPreferencesFromResource(int preferencesResId)
被标记为已弃用。
不幸的是,该方法的说明中没有提供替代方法。
为了将preferenceScreen.xml连接到匹配的PreferenceActivity,应该使用哪种方法呢?
addPreferencesFromResource(int preferencesResId)
。我想念什么吗?
我刚刚注意到一个事实,该方法在Android文档(参考条目)中已addPreferencesFromResource(int preferencesResId)
被标记为已弃用。
不幸的是,该方法的说明中没有提供替代方法。
为了将preferenceScreen.xml连接到匹配的PreferenceActivity,应该使用哪种方法呢?
addPreferencesFromResource(int preferencesResId)
。我想念什么吗?
Answers:
方法的描述中未提供任何替代方法,因为首选方法(从API级别11开始)是实例化PreferenceFragment对象,以从资源文件加载您的首选项。请参阅此处的示例代码:PreferenceActivity
为了向上面的正确答案添加更多信息,在阅读了Android-er的示例后,我发现您可以轻松地将您的偏好活动转换为偏好片段。如果您有以下活动:
public class MyPreferenceActivity extends PreferenceActivity
{
@Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.my_preference_screen);
}
}
您要做的唯一更改是创建一个内部片段类,将其addPreferencesFromResources()
移入片段,然后从活动中调用片段,如下所示:
public class MyPreferenceActivity extends PreferenceActivity
{
@Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
}
public static class MyPreferenceFragment extends PreferenceFragment
{
@Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.my_preference_screen);
}
}
}
从片段中选择更复杂的首选项可能还有其他一些细微之处。如果是这样,我希望有人在这里注明。
addPreferencesFromResources()
在PreferenceFragment的交易中贬值?从初学者的角度看,它看起来是不必要的。
@Garret Wilson非常感谢!作为android编码的新手,我一直困扰着首选项不兼容问题达数小时之久,但令我失望的是,他们不赞成将某些方法/方法用于较旧的API不支持的新方法/方法必须采取各种变通办法来使您的应用在各种设备上运行。真令人沮丧!
您的课程很棒,因为它使您可以按照喜好使用新的API继续使用新的API,但它不是向后兼容的。由于我尝试使用多种设备,因此我对其进行了一些修补,以使其能够在API 11之前的设备以及较新的API中运行:
import android.annotation.TargetApi;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
public class MyPrefsActivity extends PreferenceActivity
{
private static int prefs=R.xml.myprefs;
@Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
try {
getClass().getMethod("getFragmentManager");
AddResourceApi11AndGreater();
} catch (NoSuchMethodException e) { //Api < 11
AddResourceApiLessThan11();
}
}
@SuppressWarnings("deprecation")
protected void AddResourceApiLessThan11()
{
addPreferencesFromResource(prefs);
}
@TargetApi(11)
protected void AddResourceApi11AndGreater()
{
getFragmentManager().beginTransaction().replace(android.R.id.content,
new PF()).commit();
}
@TargetApi(11)
public static class PF extends PreferenceFragment
{
@Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(MyPrefsActivity.prefs); //outer class
// private members seem to be visible for inner class, and
// making it static made things so much easier
}
}
}
在两个仿真器(2.2和4.2)中测试成功。
为什么我的代码如此糟糕:
我是android编码的菜鸟,我不是最伟大的Java迷。
为了避免过时的警告并迫使Eclipse允许我进行编译,我不得不诉诸于注释,但是注释似乎只影响类或方法,因此我不得不将代码移至两个新方法上以利用此注释。
我不想每次将类复制并粘贴到新的PreferenceActivity时都必须两次写入xml资源ID,所以我创建了一个新变量来存储此值。
我希望这对其他人有用。
PS:对不起,我的观点是对的,但是,当您初来乍到并发现此类障碍时,您会无奈地感到沮丧!
我的方法非常接近Garret Wilson的方法(谢谢,我投票赞成;)
此外,它还提供与Android <3的向下兼容性。
我刚刚意识到我的解决方案更接近Kevin Remo的解决方案。它只是一点点的清洁(因为它不依赖于“ expection”反模式)。
public class MyPreferenceActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
onCreatePreferenceActivity();
} else {
onCreatePreferenceFragment();
}
}
/**
* Wraps legacy {@link #onCreate(Bundle)} code for Android < 3 (i.e. API lvl
* < 11).
*/
@SuppressWarnings("deprecation")
private void onCreatePreferenceActivity() {
addPreferencesFromResource(R.xml.preferences);
}
/**
* Wraps {@link #onCreate(Bundle)} code for Android >= 3 (i.e. API lvl >=
* 11).
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void onCreatePreferenceFragment() {
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new MyPreferenceFragment ())
.commit();
}
}
有关“真实”(但更复杂)的示例,请参见NusicPreferencesActivity和NusicPreferencesFragment。
@SuppressLint("NewApi")
-避免-更精确。您是否针对低API运行它?它将抛出VerifyError
@SuppressLint("NewApi")
只是不好的风格
@SuppressLint("NewApi")
在这种特殊情况下如何避免的建议呢?
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
-并非所有api都有所有警告:)
除了使用例外,还可以使用:
if (Build.VERSION.SDK_INT >= 11)
和使用
@SuppressLint("NewApi")
禁止显示警告。
除了使用PreferenceActivity
直接加载首选项外,还可以使用AppCompatActivity
或等效的PreferenceFragmentCompat
加载首选项来加载首选项。它是支持库(现在为Android Jetpack)的一部分,并提供与API 14的兼容性。
在您的中build.gradle
,为首选项支持库添加一个依赖项:
dependencies {
// ...
implementation "androidx.preference:preference:1.0.0-alpha1"
}
注意:我们将假设您已经创建了首选项XML。
对于您的活动,创建一个新的活动类。如果您使用的是实质性主题,则应扩展一个AppCompatActivity
,但是您可以通过以下方式灵活使用:
public class MyPreferencesActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_preferences_activity)
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, MyPreferencesFragment())
.commitNow()
}
}
}
现在到重要部分:创建一个片段,从XML加载您的首选项:
public class MyPreferencesFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.my_preferences_fragment); // Your preferences fragment
}
}
欲了解更多信息,请阅读Android开发者文档的PreferenceFragmentCompat
。