当我尝试跟随Android的开发者指南和教程使用偏好创建设置活动,我收到警告,例如:
“离型PreferenceActivity方法addPreferencesFromResource(INT)已过时”
两者中的代码这些行的:
getPreferenceManager().setSharedPreferencesName(PREFS_NAME);
addPreferencesFromResource(R.xml.default_values);
我知道,这仅仅是警告,但我想知道他们是否会造成任何问题,现在还是将来,当我运行的是我设计的应用程序。
public class DefaultValues extends PreferenceActivity {
static final String PREFS_NAME = "defaults";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPrefs(this);
getPreferenceManager().setSharedPreferencesName(PREFS_NAME);
addPreferencesFromResource(R.xml.default_values);
}
static SharedPreferences getPrefs(Context context) {
PreferenceManager.setDefaultValues(context, PREFS_NAME, MODE_PRIVATE,
R.xml.default_values, false);
return context.getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
}
}
Answer 1:
由于该方法已过时,建议您不要在代码中使用它,因为它是完全可能的,它可以在Android的未来版本中删除。 但是,我还没有遇到实际上已经从Android的去除方法已过时。
该方法的描述提供别无他法,因为首选的方法(如API级别11)是实例PreferenceFragment对象从资源文件中加载自己的喜好。 看到这里的示例代码: PreferenceActivity
Answer 2:
PreferenceActivity()
已过时,但PreferenceFragment()
现在也是如此。 PreferenceFragmentCompat()
现在要走的路:
添加依赖
implementation "androidx.preference:preference:1.0.0-alpha3"
或者,如果你还在使用支持库:
implementation "com.android.support:preference-v7:27.1.1"
扩展PreferenceFragmentCompat
class MyPreferenceFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.app_preferences)
}
}
显示您的片段
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager.beginTransaction().replace(android.R.id.content, MyPreferenceFragment()).commit()
}
指定preferenceTheme
在你AppTheme,添加以下偏好主题要么,这取决于你认为哪一个更好看的:
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
Answer 3:
拉夫·索德是正确的。 但是,如果你需要PreferenceFragment不好(我需要在选项卡),您可以使用此功能。 但它可以在未来的制动,从而更好地使用这只旧的API。 这是一个小修改PreferenceFragment我SupportLibrary和反思制造。
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.Preference;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.support.v4.app.Fragment;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnKeyListener;
import android.widget.ListView;
@SuppressLint("HandlerLeak")
public abstract class PreferenceFragment
extends Fragment
{
private static final String PREFERENCES_TAG = "android:preferences";
private PreferenceManager mPreferenceManager;
private ListView mList;
private boolean viewCreated;
// private boolean mHavePrefs;
// private boolean mInitDone;
/**
* The starting request code given out to preference framework.
*/
private static final int FIRST_REQUEST_CODE = 100;
private static final int MSG_BIND_PREFERENCES = 1;
private final Handler mHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
switch (msg.what) {
case MSG_BIND_PREFERENCES:
if (viewCreated) {
bindPreferences();
}
break;
}
}
};
private final Runnable mRequestFocus = new Runnable()
{
@Override
public void run()
{
mList.focusableViewAvailable(mList);
}
};
/**
* Interface that PreferenceFragment's containing activity should implement
* to be able to process preference items that wish to switch to a new
* fragment.
*/
public interface OnPreferenceStartFragmentCallback
{
/**
* Called when the user has clicked on a Preference that has a fragment
* class name associated with it. The implementation to should
* instantiate and switch to an instance of the given fragment.
*/
boolean onPreferenceStartFragment(PreferenceFragment caller,
Preference pref);
}
@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
try {
Constructor<?> constructor = PreferenceManager.class
.getDeclaredConstructor(Activity.class, int.class);
constructor.setAccessible(true);
mPreferenceManager = (PreferenceManager) constructor.newInstance(
getActivity(), FIRST_REQUEST_CODE);
} catch (Throwable e) {
throw new RuntimeException(
"Could not instantiate PreferenceManager: "
+ e.getMessage());
}
}
@Override
public final View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_preferences, null);
this.viewCreated = true;
return v;
}
// @Override
// public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Bundle savedInstanceState) {
// return inflater.inflate(R.layout.preference_list_fragment, container,
// false);
// }
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
// if (mHavePrefs) {
bindPreferences();
// }
// mInitDone = true;
if (savedInstanceState != null) {
Bundle container = savedInstanceState.getBundle(PREFERENCES_TAG);
if (container != null) {
final PreferenceScreen preferenceScreen = getPreferenceScreen();
if (preferenceScreen != null) {
preferenceScreen.restoreHierarchyState(container);
}
}
}
}
// @Override
// public void onStart() {
// super.onStart();
// IllegalAccessException
// try {
// Method m = PreferenceManager.class
// .getDeclaredMethod("setOnPreferenceTreeClickListener",
// Class.forName("android.preference.PreferenceManager$OnPreferenceTreeClickListener"));
// m.invoke(mPreferenceManager, this);
// } catch (Exception e) {
// e.printStackTrace();
// }
// mPreferenceManager.setOnPreferenceTreeClickListener(this);
// }
@Override
public void onStop()
{
super.onStop();
try {
Method m = PreferenceManager.class
.getDeclaredMethod("dispatchActivityStop");
m.setAccessible(true);
m.invoke(mPreferenceManager);
} catch (Exception e) {
e.printStackTrace();
}
// IllegalAccessException
// try {
// Method m = PreferenceManager.class
// .getDeclaredMethod("setOnPreferenceTreeClickListener",
// Class.forName("android.preference.PreferenceManager$OnPreferenceTreeClickListener"));
// m.invoke(mPreferenceManager, (Object) null);
// } catch (Exception e) {
// e.printStackTrace();
// }
// mPreferenceManager.setOnPreferenceTreeClickListener(null);
}
@Override
public void onDestroyView()
{
this.viewCreated = false;
mList = null;
mHandler.removeCallbacks(mRequestFocus);
mHandler.removeMessages(MSG_BIND_PREFERENCES);
super.onDestroyView();
}
@Override
public void onDestroy()
{
super.onDestroy();
try {
Method m = PreferenceManager.class
.getDeclaredMethod("dispatchActivityDestroy");
m.setAccessible(true);
m.invoke(mPreferenceManager);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
final PreferenceScreen preferenceScreen = getPreferenceScreen();
if (preferenceScreen != null) {
Bundle container = new Bundle();
preferenceScreen.saveHierarchyState(container);
outState.putBundle(PREFERENCES_TAG, container);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
try {
Method m = PreferenceManager.class.getDeclaredMethod(
"dispatchActivityResult", int.class, int.class,
Intent.class);
m.setAccessible(true);
m.invoke(mPreferenceManager, requestCode, resultCode, data);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Returns the {@link PreferenceManager} used by this fragment.
*
* @return The {@link PreferenceManager}.
*/
public PreferenceManager getPreferenceManager()
{
return mPreferenceManager;
}
/**
* Sets the root of the preference hierarchy that this fragment is showing.
*
* @param preferenceScreen
* The root {@link PreferenceScreen} of the preference hierarchy.
*/
public void setPreferenceScreen(PreferenceScreen preferenceScreen)
{
try {
Method m = PreferenceManager.class.getDeclaredMethod(
"setPreferences", PreferenceScreen.class);
m.setAccessible(true);
boolean result = (Boolean) m.invoke(mPreferenceManager,
preferenceScreen);
if (result && preferenceScreen != null) {
postBindPreferences();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Gets the root of the preference hierarchy that this fragment is showing.
*
* @return The {@link PreferenceScreen} that is the root of the preference
* hierarchy.
*/
public PreferenceScreen getPreferenceScreen()
{
try {
Method m = PreferenceManager.class
.getDeclaredMethod("getPreferenceScreen");
m.setAccessible(true);
return (PreferenceScreen) m.invoke(mPreferenceManager);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* Adds preferences from activities that match the given {@link Intent}.
*
* @param intent
* The {@link Intent} to query activities.
*/
public void addPreferencesFromIntent(Intent intent)
{
requirePreferenceManager();
try {
Method m = PreferenceManager.class
.getDeclaredMethod("inflateFromIntent");
m.setAccessible(true);
PreferenceScreen ps = (PreferenceScreen) m.invoke(
mPreferenceManager, intent, getPreferenceScreen());
setPreferenceScreen(ps);
} catch (Throwable e) {
}
}
/**
* Inflates the given XML resource and adds the preference hierarchy to the
* current preference hierarchy.
*
* @param preferencesResId
* The XML resource ID to inflate.
*/
public void addPreferencesFromResource(int preferencesResId)
{
requirePreferenceManager();
try {
Method m = PreferenceManager.class.getDeclaredMethod(
"inflateFromResource", Context.class, int.class,
PreferenceScreen.class);
m.setAccessible(true);
PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(
mPreferenceManager, getActivity(), preferencesResId,
getPreferenceScreen());
setPreferenceScreen(prefScreen);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* {@inheritDoc}
*/
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
try {
Method m = Preference.class.getDeclaredMethod("getFragment");
Object o = m.invoke(preference);
if (o != null
&& getActivity() instanceof OnPreferenceStartFragmentCallback) {
return ((OnPreferenceStartFragmentCallback) getActivity())
.onPreferenceStartFragment(this, preference);
}
} catch (Throwable e) {
}
}
return false;
}
/**
* Finds a {@link Preference} based on its key.
*
* @param key
* The key of the preference to retrieve.
* @return The {@link Preference} with the key, or null.
* @see PreferenceGroup#findPreference(CharSequence)
*/
public Preference findPreference(CharSequence key)
{
if (mPreferenceManager == null) {
return null;
}
return mPreferenceManager.findPreference(key);
}
private void requirePreferenceManager()
{
if (mPreferenceManager == null) {
throw new RuntimeException(
"This should be called after super.onCreate.");
}
}
private void postBindPreferences()
{
if (mHandler.hasMessages(MSG_BIND_PREFERENCES))
return;
mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();
}
private void bindPreferences()
{
final PreferenceScreen preferenceScreen = getPreferenceScreen();
if (preferenceScreen != null) {
preferenceScreen.bind(getListView());
}
}
/** @hide */
public ListView getListView()
{
ensureList();
return mList;
}
private void ensureList()
{
if (mList != null) {
return;
}
View root = getView();
if (root == null) {
throw new IllegalStateException("Content view not yet created");
}
View rawListView = root.findViewById(android.R.id.list);
if (!(rawListView instanceof ListView)) {
throw new RuntimeException(
"Content has view with id attribute 'android.R.id.list' "
+ "that is not a ListView class");
}
mList = (ListView) rawListView;
if (mList == null) {
throw new RuntimeException(
"Your content must have a ListView whose id attribute is "
+ "'android.R.id.list'");
}
mList.setOnKeyListener(mListOnKeyListener);
mHandler.post(mRequestFocus);
}
private OnKeyListener mListOnKeyListener = new OnKeyListener()
{
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
Object selectedItem = mList.getSelectedItem();
if (selectedItem instanceof Preference) {
View selectedView = mList.getSelectedView();
Preference p = (Preference) selectedItem;
try {
Method m = Preference.class.getDeclaredMethod("onKey",
View.class, int.class, KeyEvent.class);
m.setAccessible(true);
boolean result = (Boolean) m.invoke(p, selectedView,
keyCode, event);
return result;
} catch (Throwable e) {
}
}
return false;
}
};
}
Answer 4:
优选实施现在使用Fragment
秒。 下面的工作:
public class DefaultValues extends Activity {
static final String PREFS_NAME = "defaults";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Display the fragment as the main content.
if (savedInstanceState == null)
getFragmentManager().beginTransaction().add(android.R.id.content, new PrefFragment()).commit();
}
public static class PrefFragment extends PreferenceFragment
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName(PREFS_NAME);
addPreferencesFromResource(R.xml.default_values);
}
}
}
Answer 5:
如果你面临这样的方法产生警告:
addPreferencesFromResource(R.xml.default_values);
你必须使用PreferenceFragment因为API 11及以上需要这样的方法。
下面是如何使用PreferenceFragment一个例子:
1.创建/res/xml/preferences.xml来定义我们的喜好。
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="PreferenceCategory A">
<CheckBoxPreference
android:key="checkbox_preference"
android:title="title_checkbox_preference"
android:summary="summary_checkbox_preference" />
</PreferenceCategory>
<PreferenceCategory
android:title="PreferenceCategory B">
<EditTextPreference
android:key="edittext_preference"
android:title="title_edittext_preference"
android:summary="summary_edittext_preference"
android:dialogTitle="dialog_title_edittext_preference" />
</PreferenceCategory>
2.创建PrefsFragment.java扩展PreferenceFragment到addPreferencesFromResource。
package com.example.androidpreferencefragment;
import android.os.Bundle;
import android.preference.PreferenceFragment;
public class PrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
}
3.创建SetPreferenceActivity.java加载PrefsFragment。
package com.example.androidpreferencefragment;
import android.app.Activity;
import android.os.Bundle;
public class SetPreferenceActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content,
new PrefsFragment()).commit();
}
}
4.Modify主要布局,/res/layout/activity_main.xml,以显示偏好。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/padding_medium"
android:text="@string/hello_world"
tools:context=".MainActivity" />
<CheckBox
android:id="@+id/prefCheckBox"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="CheckBoxPreference" />
<TextView
android:id="@+id/prefEditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
5,主要活动,MainActivity.java。
package com.example.androidpreferencefragment;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.CheckBox;
import android.widget.TextView;
public class MainActivity extends Activity {
CheckBox prefCheckBox;
TextView prefEditText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prefCheckBox = (CheckBox)findViewById(R.id.prefCheckBox);
prefEditText = (TextView)findViewById(R.id.prefEditText);
loadPref();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
/*
* Because it's onlt ONE option in the menu.
* In order to make it simple, We always start SetPreferenceActivity
* without checking.
*/
Intent intent = new Intent();
intent.setClass(MainActivity.this, SetPreferenceActivity.class);
startActivityForResult(intent, 0);
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
//super.onActivityResult(requestCode, resultCode, data);
/*
* To make it simple, always re-load Preference setting.
*/
loadPref();
}
private void loadPref(){
SharedPreferences mySharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean my_checkbox_preference = mySharedPreferences.getBoolean("checkbox_preference", false);
prefCheckBox.setChecked(my_checkbox_preference);
String my_edittext_preference = mySharedPreferences.getString("edittext_preference", "");
prefEditText.setText(my_edittext_preference);
}
}
5.Finally,修改AndroidManifest.xml中添加SetPreferenceActivity。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidpreferencefragment"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SetPreferenceActivity"
android:label="@string/title_activity_main" >
</activity>
</application>
文章来源: Android- deprecated method warning regarding PreferenceActivity