最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【基本解决】Android中PreferenceFragment界面透明导致界面很混乱

Android crifan 4614浏览 0评论

【背景】

之前已经参考了一些已有代码,去添加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;
 }
}

然后做出来的效果却是透明的,混乱的:

android PreferenceFragment ui transparent

现在想要:

解决弹出来的配置,带列表的,供选择的,配置界面,不要是透明的,是有背景的,居中对齐的。

【解决过程】

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  

参考:

Embedding ListPreference in an activity using PreferenceFragment in Android | Knowledge by Experience

看了半天,感觉还是要:

对于显示出来的列表选项,单独增加对应layout(的xml文件)才可以的。。。

4.参考:

ListPreference Example | Android Programming Tutorials

5.继续参考官网的:

Settings | Android Developers

6.另外参考:

PreferenceFragment | Android Developers

中的“Furthermore, the preferences shown will follow the visual style of system preferences. ”

感觉是:

此处的配置界面,弹出的ListPreference的UI,是跟着系统的preference界面来的。

但是此处显示出来的效果是透明的:

难道此处测试的android的PAD中的系统的preference也是透明的?

很明显不是啊。。。

7.参考:

Demonstration of PreferenceFragment, showing a single fragment in an activity. : Fragment « Core Class « Android

结果也是“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;

但是还是警告出错:

FragmentActivity cannot be resolved to a type

所以去

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:

Issue 4611 – android – Background from PreferenceActivity is not applied to sub-PreferenceScreen – Android Open Source Project – Issue Tracker – Google Project Hosting

但是我此处不是:子的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

再去看看自己代码,然后拷贝那段代码后:

hint many choose Import FragmentManaer using android.app fix

即,使用

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模拟器中试试效果:

结果问题依旧,还是透明的:

still transparent even in avd emulater

21.参考:

java – How can I show a preferences screen on older Android devices i.e. Gingerbread and Froyo? – Stack Overflow

->

android – Was PreferenceFragment intentionally excluded from the compatibility package? – Stack Overflow

然后参考: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

中的,系统的配置界面,是什么样的。

很明显,此时才注意到,原来此时系统配置界面,的确也就是普通的透明的。。。

白色的底部。

但是又发现,不对,配置界面,是正常的,虽然是白色,但不透明的:

android pad p3110 system settings background is non-transparent and white

所以:

之前的代码,如果是和系统配置界面相同的话,那么也应该:

对于旧界面,是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/res/layout/preference_list_fragment.xml at master · kolavar/android-support-v4-preferencefragment · GitHub

看到了

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;
 }
}

效果是:

now can show self background no previous white background

很明显:

由于设置了背景色,(估计是取代了之前的透明色)

所以之前的activity中的内容,就看不到了。

40.另外参考:

java – How to change PreferenceActivity theme? – Stack Overflow

去试试:

结果没法用setTheme,因为:

The method setTheme(int) is undefined for the type SettingFragment

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中的内容),此时看起来配置界面是正常的:

during init direct call config ui so show normal

后来,TAB页面中显示内容了,再显示配置界面时,就有问题,就很混乱了:

after tab show content then show config ui so messy

所以:

可以猜测出,之前默认的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();

去调试看看:

debug see background ColorDrawable but can not find transparent

但是看不出来是不是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();
 }

效果为:

final can show config ui with expected background

点击后弹出的选项设置为:

sub config ui after click then popup

 

【总结】

最终,此处只是,很凑合,的实现了:

不用额外的Intent,不用Preference Activity,只用PreferenceFragment,解决掉了背景色透明的问题:

办法是:

在PreferenceFragment中,实现onCreateView,其中去设置背景色,即可。

背后的逻辑(推测是) :

默认的PreferenceFragment,背景色是被设置了透明色(transparent),导致:

PreferenceFragment的页面,都是透明的

而上述设置了一定的背景色之后,就因此而解决了透明的问题了。

转载请注明:在路上 » 【基本解决】Android中PreferenceFragment界面透明导致界面很混乱

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
83 queries in 0.172 seconds, using 22.23MB memory