【背景】
之前已经参考了一些已有代码,去添加Android中的配置选项的代码:
(1)/res/xml/preferences.xml
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <PreferenceCategory android:title="@string/app_setting" > <ListPreference android:key="@string/key_switch_theme" android:title="@string/title_switch_theme" android:dialogTitle="@string/title_switch_theme"/> <ListPreference android:key="@string/key_switch_language" android:title="@string/title_switch_language" android:dialogTitle="@string/title_switch_language" android:entries="@array/languages" android:entryValues="@array/language_codes" android:defaultValue="@string/pref_switch_language_default"/> </PreferenceCategory> </PreferenceScreen>
(2)/res/values/arrays.xml
<?xml version="1.0" encoding="utf-8"?> <!-- This file is /res/values/arrays.xml --> <resources> <string-array name="entries_switch_theme"> <item>@string/theme_option_Light</item> <item>@string/theme_option_Dark</item> </string-array> <string-array name="entryvalues_switch_theme"> <item>AppLightTheme</item> <item>AppBlackTheme</item> </string-array> <string-array name="languages"> <item>@string/language_option_zh_cn</item> <item>@string/language_option_en</item> </string-array> <string-array name="language_codes"> <item>zh</item> <item>en</item> </string-array> </resources>
(3)MainActivity.java
private void showPreference(){ // Display the fragment as the main content. getFragmentManager().beginTransaction() .replace(android.R.id.content, new SettingFragment()) .commit(); }
(4)SettingFragment.java
import java.util.Locale; import android.content.res.Configuration; import android.content.res.Resources; import android.os.Bundle; import android.preference.ListPreference; import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; public class SettingFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preferences); final String languageKeyString = getString(R.string.key_switch_language); ListPreference switchLanguage = (ListPreference) findPreference(languageKeyString); switchLanguage.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { String selectedLanguage = newValue.toString(); Resources res = getActivity().getResources(); Locale locale = new Locale(selectedLanguage); Locale.setDefault(locale); Configuration config = res.getConfiguration(); config.locale = locale; res.updateConfiguration(config, res.getDisplayMetrics()); SettingFragment.this.getActivity().recreate(); return true; } }); } @Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { return true; } }
然后做出来的效果却是透明的,混乱的:
现在想要:
解决弹出来的配置,带列表的,供选择的,配置界面,不要是透明的,是有背景的,居中对齐的。
【解决过程】
1.搜:
android ListPreference transparent
参考:
android – change background color of Preference – Stack Overflow
但是没太大帮助。
因为我此处不是用的activity。也不想用activity。
2.搜:
android PreferenceScreen ListPreference
参考:
android之首选项相关 Preferences(一) – 梦中一夜下江南 – 博客频道 – CSDN.NET
也还是介绍PreferenceActivity
而此处不想要弄单独的activity。
3.搜:
android PreferenceFragment ListPreference
参考:
看了半天,感觉还是要:
对于显示出来的列表选项,单独增加对应layout(的xml文件)才可以的。。。
4.参考:
ListPreference Example | Android Programming Tutorials
5.继续参考官网的:
6.另外参考:
PreferenceFragment | Android Developers
中的“Furthermore, the preferences shown will follow the visual style of system preferences. ”
感觉是:
此处的配置界面,弹出的ListPreference的UI,是跟着系统的preference界面来的。
但是此处显示出来的效果是透明的:
难道此处测试的android的PAD中的系统的preference也是透明的?
很明显不是啊。。。
7.参考:
结果也是“extends Activity”。。。
8.另外,参考之前代码, 去改为:
private void showPreference(){ // Display the fragment as the main content. // getFragmentManager().beginTransaction() // .replace(android.R.id.content, new SettingFragment()) // .commit(); getFragmentManager() .beginTransaction() .setTransition( FragmentTransaction.TRANSIT_FRAGMENT_FADE) .replace(android.R.id.content, new SettingFragment()) .addToBackStack(null).commit(); }
效果是:
问题依旧:还是透明的。。。
9.搜:
android PreferenceFragment no background
参考:
PreferenceFragment: How to remove transparency?
android – PreferenceFragment is shown transparently – Stack Overflow
本来打算去试试:
private void showPreference(){ // Display the fragment as the main content. // getFragmentManager().beginTransaction() // .replace(android.R.id.content, new SettingFragment()) // .commit(); // getFragmentManager() // .beginTransaction() // .setTransition( // FragmentTransaction.TRANSIT_FRAGMENT_FADE) // .replace(android.R.id.content, new SettingFragment()) // .addToBackStack(null).commit(); FragmentTransaction ft = getFragmentManager().beginTransaction(); SettingFragment prefs = new SettingFragment(); // This adds the newly created Preference fragment to my main layout, shown below ft.add(R.id.main_layout,prefs); // By hiding the main fragment, transparency isn't an issue ft.hide(mMyMainFragment); ft.addToBackStack(null); ft.commit(); }
但是结果mMyMainFragment等内容无法解决。
暂时放弃。
10.参考:
PreferenceFragment shows up with a transparent background | Verious
这人和我遇到的问题一样:
在不想要多创建一个Activity和PreferenceActivity的前提下,去使用Preference 而只想要用PreferenceFragment,
但是结果弄出来的PreferenceFragment(的ListPreference)是透明的背景
然后我去看看我此处用的是哪个包。
但是我此处,貌似没发现那个
android.support.v4.app.FragmentManager
但是发现了我另外用的一个类似的:
import android.support.v4.app.FragmentActivity;
和:
import android.support.v4.app.FragmentTabHost;
然后此处,先去把代码改为:
private void showPreference(){ // Display the fragment as the main content. // getFragmentManager().beginTransaction() // .replace(android.R.id.content, new SettingFragment()) // .commit(); // getFragmentManager() // .beginTransaction() // .setTransition( // FragmentTransaction.TRANSIT_FRAGMENT_FADE) // .replace(android.R.id.content, new SettingFragment()) // .addToBackStack(null).commit(); // FragmentTransaction ft = getFragmentManager().beginTransaction(); // SettingFragment prefs = new SettingFragment(); // // This adds the newly created Preference fragment to my main layout, shown below // ft.add(R.id.main_layout,prefs); // // By hiding the main fragment, transparency isn't an issue // ft.hide(mMyMainFragment); // ft.addToBackStack(null); // ft.commit(); getFragmentManager().beginTransaction() .add(android.R.id.content, new SettingFragment()) .commit(); }
结果是:
问题依旧。
然后改为:
//import android.support.v4.app.FragmentActivity; //import android.support.v4.app.FragmentTabHost; import android.app.FragmentManager;
但是还是警告出错:
所以去
change to Fragment android.app
结果其他的onCreate等函数还是出错。
所以都换成:
android.support.v4.app.FragmentActivity
试试:
结果还是和之前一样:
我只有在我的MainActivity中是:
public class MainActivity extends FragmentActivity implements ISubscriber{
其中会涉及到:
import android.support.v4.app.FragmentActivity;
而其他地方:
并没有引用到:
android.app.Fragment
不过后来发现了,代码里面,倒是真的别处,不是当前的MainActivity中,用到了那个:
android.app.Fragment
所以的确还是存在混用的。
尝试把MainActivity中的android.support.v4.app.FragmentActivity换成android.app.Fragment,没法换,因为里面的函数都会出错。
11.那就再去看看,另外一个android项目中,里面用的是哪个,
发现另外一个项目中:
完全没有用过:
android.support.v4.app.Fragment
相关的任何东西。
而和Fragment有关的,也只用到了:
android.app.Fragment
12.然后尝试把FragmentActivity换成Activity:
//import android.support.v4.app.FragmentActivity; //import android.support.v4.app.FragmentTabHost; //import android.app.FragmentManager; public class MainActivity extends Activity implements ISubscriber{ //public class MainActivity extends Fragment implements ISubscriber{ //public class MainActivity extends FragmentActivity implements ISubscriber{
结果是:
问题依旧。还是透明的。
13.算了,还是参考:
android – PreferenceFragment is shown transparently – Stack Overflow
去加一个xml试试:
(1)preference_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main_layout" android:layout_width="fill_parent" android:layout_height="fill_parent"> <!-- Uncomment for static fragment inclusion --> <!-- fragment android:name="com.legynd.ui.MyMainFragment" android:id="@+id/mainfragment" android:layout_width="match_parent" android:layout_height="match_parent" / --> </RelativeLayout>
但是对于代码:
FragmentTransaction ft = getFragmentManager().beginTransaction(); SettingFragment prefs = new SettingFragment(); // This adds the newly created Preference fragment to my main layout, shown below ft.add(R.layout.preference_layout,prefs); // By hiding the main fragment, transparency isn't an issue ft.hide(mMyMainFragment); ft.addToBackStack(null); ft.commit();
其中的:
mMyMainFragment
还是无法处理:
当然是处于自己的MainActivity中,又没有实例去隐藏。。。
所以暂时注释掉:
FragmentTransaction ft = getFragmentManager().beginTransaction(); SettingFragment prefs = new SettingFragment(); // This adds the newly created Preference fragment to my main layout, shown below ft.add(R.layout.preference_layout,prefs); // By hiding the main fragment, transparency isn't an issue //ft.hide(mMyMainFragment); ft.addToBackStack(null); ft.commit();
结果:
直接就挂了:
04-24 09:55:18.971: E/AndroidRuntime(4770): FATAL EXCEPTION: main 04-24 09:55:18.971: E/AndroidRuntime(4770): java.lang.IllegalArgumentException: No view found for id 0x7f030008 (xxx:layout/preference_layout) for fragment SettingFragment{21170298 #0 id=0x7f030008} 04-24 09:55:18.971: E/AndroidRuntime(4770): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:895) 04-24 09:55:18.971: E/AndroidRuntime(4770): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1075) 04-24 09:55:18.971: E/AndroidRuntime(4770): at android.app.BackStackRecord.run(BackStackRecord.java:682) 04-24 09:55:18.971: E/AndroidRuntime(4770): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1455) 04-24 09:55:18.971: E/AndroidRuntime(4770): at android.app.FragmentManagerImpl$1.run(FragmentManager.java:441) 04-24 09:55:18.971: E/AndroidRuntime(4770): at android.os.Handler.handleCallback(Handler.java:725) 04-24 09:55:18.971: E/AndroidRuntime(4770): at android.os.Handler.dispatchMessage(Handler.java:92) 04-24 09:55:18.971: E/AndroidRuntime(4770): at android.os.Looper.loop(Looper.java:176) 04-24 09:55:18.971: E/AndroidRuntime(4770): at android.app.ActivityThread.main(ActivityThread.java:5279) 04-24 09:55:18.971: E/AndroidRuntime(4770): at java.lang.reflect.Method.invokeNative(Native Method) 04-24 09:55:18.971: E/AndroidRuntime(4770): at java.lang.reflect.Method.invoke(Method.java:511) 04-24 09:55:18.971: E/AndroidRuntime(4770): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) 04-24 09:55:18.971: E/AndroidRuntime(4770): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 04-24 09:55:18.971: E/AndroidRuntime(4770): at dalvik.system.NativeStart.main(Native Method)
14.再搜:
android PreferenceScreen not show background
只是找到了子PreferenceScreen的不能设置背景色的一个bug:
但是我此处不是:子的PreferenceScreen,也不完全是背景色,而是主题不生效->变透明了。
15.搜:
android PreferenceScreen theme not work
但是找到的都只是PreferenceActivity,而不是PreferenceFragment。
16.算了,还是好好再去看看官网的解释:
PreferenceFragment | Android Developers
然后注意到之前的代码:
getFragmentManager().beginTransaction() .replace(android.R.id.content, new SettingFragment()) .commit();
和:
getFragmentManager().beginTransaction() .add(android.R.id.content, new SettingFragment()) .commit();
一个是replace,一个是add,估计是:
对于add来说,就是在原先的UI上面叠加
而对于replace,就是去掉之前的UI,完全显示新的配置界面
所以,还是再去改为replace的代码:
getFragmentManager().beginTransaction() .replace(android.R.id.content, new SettingFragment()) .commit();
再此基础上,再去想办法用上“the visual style of system preferences ”,使得不再透明。
17.搜:
android PreferenceScreen getFragmentManager
参考:
Android 程式开发:(十三)特殊碎片 —— 13.3 PreferenceFragment – 修炼 – 博客频道 – CSDN.NET
再去看看自己代码,然后拷贝那段代码后:
即,使用
Import ‘FragmentManager’ (android.app)
(而不是使用那个 Import ‘FragmentManager’ (android.support.v4.app))
然后代码如下:
import android.app.FragmentManager; import android.app.FragmentTransaction; public class MainActivity extends Activity implements ISubscriber{ ...... FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); SettingFragment settingFragment = new SettingFragment(); fragmentTransaction.replace(android.R.id.content, settingFragment); fragmentTransaction.addToBackStack(null); fragmentTransaction.commit(); ...... }
结果是:
问题依旧,还是透明的。。
18.再把上述代码,移动到MainActivity的onCreate中:
import android.app.FragmentManager; import android.app.FragmentTransaction; public class MainActivity extends Activity implements ISubscriber{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); 。。。。。。 //for debug showPreference(); }
再去测试测试效果:
问题依旧。
19.重新去完整的对比一下自己的代码,和别人的代码,到底是否还有其他什么不一样。
去测试一个简单的,只包含一个checkbox的配置界面:
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <PreferenceCategory android:title="@string/app_setting" > <CheckBoxPreference android:title="Checkbox" android:defaultValue="false" android:summary="True of False" android:key="checkboxPref" /> </PreferenceCategory> </PreferenceScreen>
试试效果:
结果竟然挂了:
04-24 10:27:14.231: E/AndroidRuntime(6421): FATAL EXCEPTION: main 04-24 10:27:14.231: E/AndroidRuntime(6421): java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx.yyy.zzz/xxx.yyy.zzz.aaa.MainActivity}: java.lang.NullPointerException 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2245) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2295) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.app.ActivityThread.access$700(ActivityThread.java:150) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.os.Handler.dispatchMessage(Handler.java:99) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.os.Looper.loop(Looper.java:176) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.app.ActivityThread.main(ActivityThread.java:5279) 04-24 10:27:14.231: E/AndroidRuntime(6421): at java.lang.reflect.Method.invokeNative(Native Method) 04-24 10:27:14.231: E/AndroidRuntime(6421): at java.lang.reflect.Method.invoke(Method.java:511) 04-24 10:27:14.231: E/AndroidRuntime(6421): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) 04-24 10:27:14.231: E/AndroidRuntime(6421): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 04-24 10:27:14.231: E/AndroidRuntime(6421): at dalvik.system.NativeStart.main(Native Method) 04-24 10:27:14.231: E/AndroidRuntime(6421): Caused by: java.lang.NullPointerException 04-24 10:27:14.231: E/AndroidRuntime(6421): at xxx.yyy.zzz.aaa.SettingFragment.onCreate(SettingFragment.java:47) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.app.Fragment.performCreate(Fragment.java:1677) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:872) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1075) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.app.BackStackRecord.run(BackStackRecord.java:682) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1455) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.app.Activity.performStart(Activity.java:5276) 04-24 10:27:14.231: E/AndroidRuntime(6421): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2218) 04-24 10:27:14.231: E/AndroidRuntime(6421): ... 11 more
想起来了:
是SettingFragment中,有额外的代码所导致的。。。
所以暂时注释掉。
结果问题依旧:还是透明的。
20.当前代码一直在真机PAD上尝试的,现在弄到AVD模拟器中试试效果:
结果问题依旧,还是透明的:
21.参考:
->
然后参考:PreferenceFragment的例子:
cw-android/Prefs/FragmentsBC at master · commonsguy/cw-android · GitHub
结果是PreferenceActivity的例子。。。。
不过在StockPreferenceFragment.java中也是看到了PreferenceFragment的例子。
但是还是没看到,对于我此处的代码,有啥值得参考的。
22.参考:
PreferenceFragment | Android Developers
发现其中有示例代码,但是对于PrefsFragment,却没有写怎么被调用的。
所以去搜:
android PrefsFragment
结果就真的搜到了,遇到和我类似问题的(需要翻墙看):
Android-er: Example of using PreferenceFragment
中有人回复的:
“I’ve been struggling with this problem for hours and hours where just replacing the fragments left the preferences fragment background as transparent and it would overlay on top of other content.
This fixed that for me, so thanks!!”
结果其中调用PrefsFragment的方式,也只是:
getFragmentManager().beginTransaction().replace(android.R.id.content, new PrefsFragment()).commit();
试试这个代码:
getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingFragment()).commit();
和我之前的,是一样的:
问题依旧。
23.参考:
Preference Fragments | Android Programming Tutorials
其中也可以看出:
他那里显示出来的效果,也还是透明的:
底部是白色的。
24.然后此刻想起来,去看看:
之前测试的android真机:PAD
中的,系统的配置界面,是什么样的。
很明显,此时才注意到,原来此时系统配置界面,的确也就是普通的透明的。。。
白色的底部。
但是又发现,不对,配置界面,是正常的,虽然是白色,但不透明的:
所以:
之前的代码,如果是和系统配置界面相同的话,那么也应该:
对于旧界面,是replace掉了,
显示新配置界面,不是透明,而是白色背景,才对的。
25.此处另外单独弄一个类似于MainActivity的Activity,去测试一下此配置界面,在新的独立的Activity中,是否可以正常显示不透明的背景:
但是在参考:
Android 程式开发:(十三)特殊碎片 —— 13.3 PreferenceFragment – 修炼 – 博客频道 – CSDN.NET
去尝试,重新弄一个类似的PreferenceFragmentExampleActivity时,发现:
该帖子中的demo,实际上也是遇到和我此处类似的问题:
显示出来的配置界面,也是透明的->实际上没有覆盖原先的Activity中的内容->所以会导致内容重叠和混乱。
26.另外看到之前看过的那个:
PreferenceFragment shows up with a transparent background | Verious
提到了:
“added the following to my MainActivity
‘s onOptionsItemSelected
: ”
所以,感觉好像是:
还是要参考之前的另外的android项目中,去添加对应的
public class BaseActivity extends Activity {
然后其中实现对应的:
onCreateOptionsMenu
和:
onOptionsItemSelected
然后onOptionsItemSelected中实现对应的:
getFragmentManager的beginTransaction去跳转到配置界面。
不过研究了下别人的代码,貌似和我此处没区别。。。
27.再去试试:
getFragmentManager() .beginTransaction() .setTransition( FragmentTransaction.TRANSIT_FRAGMENT_FADE) .replace(android.R.id.content, new SettingFragment()) .addToBackStack(null).commit();
28.去搜:
android PrefsFragment theme
参考:
android – Adding theme support for app using listpreference – Stack Overflow
没帮助。
29.再去搜:
android PreferenceFragment theme
参考:
Android Preference Fragment Text Color – Stack Overflow
没帮助。
android – Apply custom theme to PreferenceFragment – Stack Overflow
没人回答。
30.搜:
android PreferenceFragment 透明
参考:
Android Fragement学习笔记(三)—-PreferenceFragment的使用 – Mr梵谷的专栏 – 博客频道 – CSDN.NET
中,有人评论中提到了,是通过“原来新建一个Activity就可以解决PreferenceFragment透明的问题 ”
还是没达到我的目的:
不想要通过Activity或者Intent,而就是使用PreferenceFragment,如果解决透明的问题。
不过,此处该贴,倒是貌似是翻译自官网文档的,
其代码,貌似值得好好参考参考的,毕竟也是用到了PreferenceFragment。
看了后,还是没法参考,因为其还是用到了Intent等内容。
31.再参考之前就看到的:
PreferenceFragment: How to remove transparency?
然后看到那人说其解决了:
“Ok I figured it out. I had defined the initial fragment in the XML file for the main view. You can’t replace a fragment defined in this way via a fragment transaction – you can only replace fragments that you added programmatically. That’s why the initial fragment remained visible in the background.
So the solution was to remove the initial fragment from main.xml layout file, and add it to the initial view using fragmentTransaction.add() instead. This way the initial fragment is successfully replaced when the preference fragment is called, and is no longer visible in the background.”
但是我此处是:
对于MainActivity中,onCreate中,使用的Layout:
R.layout.activity_main
所对应的xml中没有fragment
而对应他的
fragmentTransaction.add
我此处的是:
getFragmentManager() .beginTransaction() .setTransition( FragmentTransaction.TRANSIT_FRAGMENT_FADE) .replace(android.R.id.content, new SettingFragment()) .addToBackStack(null).commit();
不过,后来才看清楚:
原来那个楼主也是坑爹的:
其最后是用了外的Intent和PreferenceActivity
而不是PreferenceFragment!!!
你妹的。。
32.自己再试试:
getFragmentManager() .beginTransaction() .setTransition( FragmentTransaction.TRANSIT_FRAGMENT_FADE) //.replace(android.R.id.content, new SettingFragment()) .add(android.R.id.content, new SettingFragment()) .addToBackStack(null).commit();
结果:
问题依旧,还是透明的。
33.参考:
Fragment & Headers 使用 – 老菜_ – 博客园
好像是:
需要把fragment,加到对应的MainActivity的xml中?
去试试:
没搞定。
34.去试试改为:
getFragmentManager() .beginTransaction() .setTransition( FragmentTransaction.TRANSIT_FRAGMENT_FADE) //.replace(android.R.id.content, new SettingFragment()) //.add(android.R.id.content, new SettingFragment()) .replace(android.R.id.tabcontent, new SettingFragment()) .addToBackStack(null).commit();
结果:
问题依旧。
34.搜:
android PreferenceFragment transparent
参考:
How to change PreferenceFragment Colors (Summary Text Color included) | Android & Multimedia Tips
倒是看到,自定义PreferenceFragment主题的办法。
35.参考:
看到了
android-support-v4-preferencefragment
中的,默认的背景是透明的:
android:background="@android:color/transparent"
所以推测:
不会是:
对于非v4的android,即:
import android.app.FragmentManager; import android.app.FragmentTransaction;
对应的内部的代码实现,也是:
android:background="@android:color/transparent"
吧?如果是那样的话,那倒是真的会出现此处的透明的现象了。
35.去看看:
之前的配置的app的theme中,是否有设置preference的方面的内容;
搜:
PreferenceFragment | Android Developers
<!-- The visual style of a child is defined by this styled theme attribute. --> <CheckBoxPreference android:key="child_checkbox_preference" android:dependency="parent_checkbox_preference" android:layout="?android:attr/preferenceLayoutChild" android:title="@string/title_child_preference" android:summary="@string/summary_child_preference" />
但是没用。
36.搜:
android preferencefragment style
参考:
PreferenceFragment的简单使用 – – 博客频道 – CSDN.NET
去试试:
/res/layout/preference_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/preference_layout" android:layout_width="fill_parent" android:layout_height="fill_parent"> <!-- Uncomment for static fragment inclusion --> <!-- fragment android:name="com.legynd.ui.MyMainFragment" android:id="@+id/mainfragment" android:layout_width="match_parent" android:layout_height="match_parent" / --> </RelativeLayout>
代码中:
getFragmentManager() .beginTransaction() .setTransition( FragmentTransaction.TRANSIT_FRAGMENT_FADE) //.replace(android.R.id.content, new SettingFragment()) //.add(android.R.id.content, new SettingFragment()) //.replace(android.R.id.tabcontent, new SettingFragment()) .replace(R.id.preference_layout, new SettingFragment()) .addToBackStack(null).commit();
结果:
挂了:
04-24 13:45:05.080: E/AndroidRuntime(1776): FATAL EXCEPTION: main 04-24 13:45:05.080: E/AndroidRuntime(1776): java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx.yyy.zzz/xxx.yyy.zzz.aaa.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f0b0021 for fragment SettingFragment{b35991d8 #0 id=0x7f0b0021} 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059) 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.app.ActivityThread.access$600(ActivityThread.java:130) 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.os.Handler.dispatchMessage(Handler.java:99) 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.os.Looper.loop(Looper.java:137) 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.app.ActivityThread.main(ActivityThread.java:4745) 04-24 13:45:05.080: E/AndroidRuntime(1776): at java.lang.reflect.Method.invokeNative(Native Method) 04-24 13:45:05.080: E/AndroidRuntime(1776): at java.lang.reflect.Method.invoke(Method.java:511) 04-24 13:45:05.080: E/AndroidRuntime(1776): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 04-24 13:45:05.080: E/AndroidRuntime(1776): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 04-24 13:45:05.080: E/AndroidRuntime(1776): at dalvik.system.NativeStart.main(Native Method) 04-24 13:45:05.080: E/AndroidRuntime(1776): Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f0b0021 for fragment SettingFragment{b35991d8 #0 id=0x7f0b0021} 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:823) 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035) 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.app.BackStackRecord.run(BackStackRecord.java:635) 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1397) 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.app.Activity.performStart(Activity.java:5017) 04-24 13:45:05.080: E/AndroidRuntime(1776): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2032) 04-24 13:45:05.080: E/AndroidRuntime(1776): ... 11 more
37.搜:
android PreferenceScreen style
参考:
Background in PreferenceScreen – Google Groups
但是都是用的是PreferenceActivity,不是我要的。
38.这里:
android Preference相关样式修改 – 空指针 – ITeye技术网站
也有总结,但是没具体说明如何操作PreferenceFragment 。
39.在PreferenceFragment的onCreate中设置一下background试试效果:
添加代码:
public class SettingFragment extends PreferenceFragment { ...... @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); view.setBackgroundColor(getResources().getColor(R.color.xxx)); return view; } }
效果是:
很明显:
由于设置了背景色,(估计是取代了之前的透明色)
所以之前的activity中的内容,就看不到了。
40.另外参考:
java – How to change PreferenceActivity theme? – Stack Overflow
去试试:
结果没法用setTheme,因为:
The method setTheme(int) is undefined for the type SettingFragment
41.但是去试试另外的:
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); //view.setBackgroundColor(getResources().getColor(R.color.xxx)); view.setBackgroundColor(Color.TRANSPARENT); return view; }
效果是:
问题依旧,但是注意到一个现象。
初始化期间,由于代码直接调用去显示配置界面,此时,由于背景没显示其他(TAB中的内容),此时看起来配置界面是正常的:
后来,TAB页面中显示内容了,再显示配置界面时,就有问题,就很混乱了:
所以:
可以猜测出,之前默认的PreferenceFragment的背景色,的确就是transparent的,就是等价于此处的:
view.setBackgroundColor(Color.TRANSPARENT);
的。
所以去用代码:
View view = super.onCreateView(inflater, container, savedInstanceState); //view.setBackgroundColor(Color.TRANSPARENT); Drawable background= view.getBackground(); Object bkgClass = background.getClass();
去调试看看:
但是看不出来是不是Color.TRANSPARENT。。。
42.再先去试试:
view.setBackground(null);
结果是:
问题依旧。
43.再去试试:
Drawable currBackground= container.getBackground(); view.setBackground(currBackground);
效果是:
currBackground为null->和之前的效果一样,还是没背景色,还是问题依旧。
44.最后用代码:
(1)SettingFragment.java
实现代码:
...... public class SettingFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preferences); ...... } @Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { return true; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); view.setBackgroundResource(android.R.color.white); return view; }
(2)调用代码
public class MainActivity extends Activity
中去调用:
private void showPreference(){ // Display the fragment as the main content. getFragmentManager().beginTransaction() .replace(android.R.id.content, new SettingFragment()) .commit(); }
效果为:
点击后弹出的选项设置为:
【总结】
最终,此处只是,很凑合,的实现了:
不用额外的Intent,不用Preference Activity,只用PreferenceFragment,解决掉了背景色透明的问题:
办法是:
在PreferenceFragment中,实现onCreateView,其中去设置背景色,即可。
背后的逻辑(推测是) :
默认的PreferenceFragment,背景色是被设置了透明色(transparent),导致:
PreferenceFragment的页面,都是透明的
而上述设置了一定的背景色之后,就因此而解决了透明的问题了。