如何在 Android 上创建 Preference Activity 和 Preference Fragment?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23523806/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you create Preference Activity and Preference Fragment on Android?
提问by WannaGetHigh
As I was following an old tutorial (Créez des applications pour Android -> openclassroom) I got stuck on this deprecated method addPreferencesFromResource(int id)
from the PreferenceActivity class.
当我在学习一个旧教程(Créez des applications pour Android -> openclassroom)时,我陷入addPreferencesFromResource(int id)
了 PreferenceActivity 类中这个已弃用的方法上。
So my question is :
所以我的问题是:
What is the new way of creating Preferences in Android ?
在 Android 中创建首选项的新方法是什么?
回答by WannaGetHigh
I found this post (What to use instead of “addPreferencesFromResource” in a PreferenceActivity?) that help me understand that you have to go through a PreferenceFragment
in order to do it.
我发现这篇文章(在 PreferenceActivity 中使用什么而不是“addPreferencesFromResource”?)帮助我理解你必须通过 aPreferenceFragment
才能做到这一点。
In the following explanation I use your.package.
just to show that you have to put the package name. Everybody has its own package so please replace it with your package.
在下面的解释中,我your.package.
只是为了表明您必须输入包名称。每个人都有自己的包,所以请用你的包替换它。
lets begin :
让我们开始 :
1. Preference Fragment
1. 偏好片段
Create your PreferenceFragment class
MyPreferenceFragment
public class MyPreferenceFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.fragment_preference); } }
创建您的 PreferenceFragment 类
我的首选项片段
public class MyPreferenceFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.fragment_preference); } }
Then the associated xml resource
fragment_preference.xml(in the folder res/xml of your project)
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="FOO"> <CheckBoxPreference android:key="checkBoxPref" android:title="check it out" android:summary="click this little box"/> </PreferenceCategory> </PreferenceScreen>
That's all for the
Fragment
part.
然后关联的xml资源
fragment_preference.xml(在您项目的文件夹 res/xml 中)
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="FOO"> <CheckBoxPreference android:key="checkBoxPref" android:title="check it out" android:summary="click this little box"/> </PreferenceCategory> </PreferenceScreen>
这就是全部
Fragment
。
2. Preference Activity
2. 偏好活动
Create the PreferenceActivity class
MyPreferenceActivity
public class MyPreferenceActivity extends PreferenceActivity { @Override public void onBuildHeaders(List<Header> target) { loadHeadersFromResource(R.xml.headers_preference, target); } @Override protected boolean isValidFragment(String fragmentName) { return MyPreferenceFragment.class.getName().equals(fragmentName); } }
Do not forgetto override
isValidFragment(String fragmentName)
method as you will get punched in the face by your application ! ;) More seriously I have no idea why you need to do this but it is needed. If someone has an explanation about this I'd gladly read it :)EDIT :
Thanks to kirtan403 I now know why it is needed : it has to be set because of an (android framework fragment injection).
As you can see in the
onBuildHeaders(List<Header> target)
we load another xml file that contain the headersof the preference. In short, headers are the left part of the preference and the fragment are the right part (for tablet). For a phone you will first have the headers and when you click on an item the corresponding fragment will be put on top of the headers list.Read this article (Multi-pane development in Android with Fragments - Tutorial) the images explain themselves.
创建 PreferenceActivity 类
我的偏好活动
public class MyPreferenceActivity extends PreferenceActivity { @Override public void onBuildHeaders(List<Header> target) { loadHeadersFromResource(R.xml.headers_preference, target); } @Override protected boolean isValidFragment(String fragmentName) { return MyPreferenceFragment.class.getName().equals(fragmentName); } }
不要忘记覆盖
isValidFragment(String fragmentName)
方法,因为你会被你的应用程序打在脸上!;) 更严重的是,我不知道为什么你需要这样做,但它是必需的。如果有人对此有解释,我很乐意阅读它:)编辑 :
感谢 kirtan403,我现在知道为什么需要它:由于(android 框架片段注入)必须设置它。
正如您在 中看到的,
onBuildHeaders(List<Header> target)
我们加载了另一个包含首选项标题的xml 文件。简而言之,标题是首选项的左侧部分,片段是右侧部分(对于平板电脑)。对于手机,您将首先拥有标题,当您单击一个项目时,相应的片段将放在标题列表的顶部。阅读这篇文章(使用 Fragments 在 Android 中进行多窗格开发 - 教程),图像会自行解释。
Then the associated xml resource
headers_preference.xml(in the folder res/xml of your project)
<?xml version="1.0" encoding="utf-8"?> <preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> <header android:fragment="your.package.MyPreferenceFragment" android:title="Goto: Preference fragment" android:summary="An example of some preferences." /> </preference-headers>
As you may have noticed in the headersection you have :
android:fragment="your.package.MyPreferenceFragment"
This will act as a Link to the fragment you want to show. On Tablet it will load on the right part and on the phone it will load on top of the current view.
然后关联的xml资源
headers_preference.xml(在您项目的文件夹 res/xml 中)
<?xml version="1.0" encoding="utf-8"?> <preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> <header android:fragment="your.package.MyPreferenceFragment" android:title="Goto: Preference fragment" android:summary="An example of some preferences." /> </preference-headers>
正如您在标题部分可能已经注意到的那样:
android:fragment="your.package.MyPreferenceFragment"
这将充当您要显示的片段的链接。在平板电脑上,它将加载到右侧部分,而在手机上,它将加载到当前视图的顶部。
3. Android Manifest
3. 安卓清单
Now what you should do is to add your Activity to the AndroidManifest.xml
file.
现在您应该做的是将您的活动添加到AndroidManifest.xml
文件中。
Inside the application
section add these lines :
在该application
部分内添加这些行:
<activity
android:name="your.package.MyPreferenceActivity"
android:label="Preferences">
</activity>
You will probably tell me :
你可能会告诉我:
"Oh darling you forgot to put android:launchMode="singleTask"in your actvity"
“哦,亲爱的,你忘了把android:launchMode="singleTask"放在你的活动中”
But DO NOT PUT THISas you will never load your fragment on phone. This error was solved by a great man ! This is the link to his blog (Android header preferences on small screen/phone).
但是不要放这个,因为你永远不会在手机上加载你的片段。这个错误被一个伟人解决了!这是他的博客的链接(小屏幕/手机上的 Android 标题首选项)。
4. Start the Preferences from Menu
4. 从菜单启动首选项
Finally you need to add the ability to show this Preference !! To do so you will need 3 things :
最后,您需要添加显示此首选项的功能!!为此,您将需要 3 件事:
The Menu
menu.xml(in the folder res/menu of your project)
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/preferences" android:title="Preferences" /> </menu>
菜单
menu.xml(在您项目的文件夹 res/menu 中)
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/preferences" android:title="Preferences" /> </menu>
Loading this Menu in your Main activity (not the PreferenceActivity) under the method
onCreateOptionsMenu(Menu menu)
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); return true; }
在方法下的 Main 活动(不是 PreferenceActivity)中加载此菜单
onCreateOptionsMenu(Menu menu)
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); return true; }
Starting the
MyPreferenceActivity
Activity when you click on that button.For that you will need to override the
onOptionsItemSelected(MenuItem item)
method in your Main activity.@Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { case R.id.preferences: { Intent intent = new Intent(); intent.setClassName(this, "your.package.MyPreferenceActivity"); startActivity(intent); return true; } } return super.onOptionsItemSelected(item); }
MyPreferenceActivity
单击该按钮时启动活动。为此,您需要覆盖
onOptionsItemSelected(MenuItem item)
Main 活动中的方法。@Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { case R.id.preferences: { Intent intent = new Intent(); intent.setClassName(this, "your.package.MyPreferenceActivity"); startActivity(intent); return true; } } return super.onOptionsItemSelected(item); }
Et voila les amis !
瞧瞧朋友们!
I haven't tested this code. I took it and modified it from my own code so I may have not well copy pasted things. If you encounter errors tell me, I'll try to figure out the problem and fix this.
我还没有测试过这段代码。我拿了它并从我自己的代码中修改了它,所以我可能没有很好地复制粘贴的东西。如果您遇到错误告诉我,我会尝试找出问题并解决此问题。
I hope this post will help some people out there :D
我希望这篇文章能帮助一些人:D
Cheers !
干杯!
回答by Gene Bo
I liked the solution from this post: http://alvinalexander.com/android/android-tutorial-preferencescreen-preferenceactivity-preferencefragment
我喜欢这篇文章中的解决方案:http: //alvinalexander.com/android/android-tutorial-preferencescreen-preferenceactivity-preferencefragment
.. because it seems the most compact for someone that just needs something very basic up and running quickly. It has only one .java file and two small xml files.
..因为对于只需要非常基本的东西并快速运行的人来说,它似乎是最紧凑的。它只有一个 .java 文件和两个小的 xml 文件。
Activity Config REMINDERS
After adding the 3 files to your project, Don't forget to
A) Add the Prefs Activity to Manifest file
B) Add some way to launch the Prefs Activity .. e.g., a Button or Menu item
活动配置提醒
将 3 个文件添加到您的项目后,不要忘记
A) 将 Prefs Activity 添加到 Manifest 文件
B) 添加某种方式来启动 Prefs Activity .. 例如,按钮或菜单项
Add the following files to your project. Use the order they are listed in to avoid compile errors.
将以下文件添加到您的项目中。使用它们列出的顺序以避免编译错误。
Add /res/values/array.xml
<resources> <string-array name="listArray"> <item>Ace</item> <item>Club</item> </string-array> <string-array name="listValues"> <item>Ace</item> <item>Club</item> </string-array> </resources>
Add /res/xml/preferences.xml
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <EditTextPreference android:title="Your Name" android:key="username" android:summary="Please provide your username"></EditTextPreference> <CheckBoxPreference android:title="Application Updates" android:defaultValue="false" android:summary="This option if selected will allow the application to check for latest versions." android:key="applicationUpdates" /> <ListPreference android:title="Download Details" android:summary="Select the kind of data that you would like to download" android:key="downloadType" android:defaultValue="Ace" android:entries="@array/listArray" android:entryValues="@array/listValues" /> </PreferenceScreen>
Add the Activity code
public class AppPreferenceActivity extends PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit(); checkValues(); } public static class MyPreferenceFragment extends PreferenceFragment { @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); } } private void checkValues() { SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); String strUserName = sharedPrefs.getString("username", "NA"); boolean bAppUpdates = sharedPrefs.getBoolean("applicationUpdates",false); String downloadType = sharedPrefs.getString("downloadType","1"); String msg = "Cur Values: "; msg += "\n userName = " + strUserName; msg += "\n bAppUpdates = " + bAppUpdates; msg += "\n downloadType = " + downloadType; Toaster.shortDebug(msg); } }
添加/res/values/array.xml
<resources> <string-array name="listArray"> <item>Ace</item> <item>Club</item> </string-array> <string-array name="listValues"> <item>Ace</item> <item>Club</item> </string-array> </resources>
添加/res/xml/preferences.xml
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <EditTextPreference android:title="Your Name" android:key="username" android:summary="Please provide your username"></EditTextPreference> <CheckBoxPreference android:title="Application Updates" android:defaultValue="false" android:summary="This option if selected will allow the application to check for latest versions." android:key="applicationUpdates" /> <ListPreference android:title="Download Details" android:summary="Select the kind of data that you would like to download" android:key="downloadType" android:defaultValue="Ace" android:entries="@array/listArray" android:entryValues="@array/listValues" /> </PreferenceScreen>
添加活动代码
public class AppPreferenceActivity extends PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit(); checkValues(); } public static class MyPreferenceFragment extends PreferenceFragment { @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); } } private void checkValues() { SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); String strUserName = sharedPrefs.getString("username", "NA"); boolean bAppUpdates = sharedPrefs.getBoolean("applicationUpdates",false); String downloadType = sharedPrefs.getString("downloadType","1"); String msg = "Cur Values: "; msg += "\n userName = " + strUserName; msg += "\n bAppUpdates = " + bAppUpdates; msg += "\n downloadType = " + downloadType; Toaster.shortDebug(msg); } }