大家好我已经在清单文件中设置了这样的主题:
android:theme="@android:style/Theme.Light"
但是我在首选项活动中遇到了问题,在主要首选项中主题显示确定,但如果我得到一个子偏好,主题变得混乱,它不是白色应该,它是全黑的,并且字体是黑色的,所以你看不到多少,当我开始点击任何项目时,他们有时会变成白色,但很快就会变成黑色。这只发生在2.1,在真实设备和仿真器中。在运行1.6的模拟器上测试,它运行正常。以下是首选项xml文件的代码的一部分:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen
android:title="@string/account">
<CheckBoxPreference
android:key="enable_account"
android:title="@string/account_use"
android:summary="@string/account_summ" />
<EditTextPreference
android:key="username"
android:title="@string/login"
android:dependency="enable_account"
android:summary="@string/login_summ" />
<EditTextPreference
android:key="password"
android:title="@string/password"
android:dependency="enable_account"
android:summary="@string/password_summ"
android:password="true" />
</PreferenceScreen>
这是截图:
alt text http://i39.tinypic.com/16hnhh3.png
有任何解决方法吗?
答案 0 :(得分:15)
有人刚刚在http://code.google.com/p/android/issues/detail?id=4611
发布了一个解决方法简而言之,顶级首选项屏幕似乎识别主题但嵌套的主题不是。因此,变通方法建议为嵌套的PreferenceScreen创建顶级PreferenceActivity,然后通过intent调用此新活动:
<PreferenceScreen android:key="key1"
android:title="1 Item"
android:summary="">
<intent android:action="android.intent.action.VIEW"
android:targetPackage="com.example"
android:targetClass="com.example.PreferenceActivity2"/>
</PreferenceScreen>
除了应用程序本身,我没有必要将主题应用于任何内容。
答案 1 :(得分:4)
您还可以使用此技术覆盖内部首选项屏幕的样式:
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) {
super.onPreferenceTreeClick(preferenceScreen, preference);
if (preference != null) {
if (preference instanceof PreferenceScreen) {
if (((PreferenceScreen) preference).getDialog() != null) {
((PreferenceScreen) preference)
.getDialog()
.getWindow()
.getDecorView()
.setBackgroundDrawable(
this
.getWindow()
.getDecorView()
.getBackground()
.getConstantState()
.newDrawable()
);
}
}
}
return false;
}
此代码将主要首选项屏幕的样式应用于单击的首选项屏幕。
答案 2 :(得分:3)
最后我发现如何以编程方式更改主题“PreferenceActivity”(通过java代码)
改变主题只需这样:
@Override
public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.Holo_Theme_Light);
super.onCreate(savedInstanceState);
}
始终在setTheme(R.style.yourtheme);
方法之前调用super.onCreate(savedInstanceState);
方法。通过这样做,它将产生如下所示的结果。
就是这样。
如果您在setTheme(R.style.yourtheme);
方法之后调用super.onCreate(savedInstanceState);
方法,则会产生如下所示的结果。
注意:嵌套的PreferenceScreen无法识别主题。要将主题应用于嵌套的PreferenceScreen,您必须为该嵌套的PreferenceScreen制作另一个PreferenceActivity,并在那里调用setTheme(R.style.yourtheme);
方法。
答案 3 :(得分:2)
答案 4 :(得分:0)
有一个更简单的解决方案,如果你可以使用看似黑魔法的东西来实现这个目标......
查看PreferenceScreen#showDialog(Bundle)
的来源,我们看到该对话框是使用通过mContext.getThemeResId()
获得的主题资源创建的,然后在ContextThemeWrapper
中使用。
这可以帮助我们,因为Context
中使用的PreferenceScreen
实际上是我们的PreferenceActivity
,所以我们所要做的就是覆盖getThemeResId()
方法(这是公共API的隐藏,提供我们的自定义主题,子PreferenceScreen现在使用我们想要的任何自定义主题资源!
/**
* This is a hack to provide our own theme for the PreferenceScreen's dialog.
*
* @see android.preference.PreferenceScreen#showDialog(Bundle)
*/
public int getThemeResId() {
return R.style.Theme_MyApp_PreferenceScreen;
}
请注意,由于此方法使用@hide
进行注释,因此我们无法使用通常在此情况下使用的@Override
注释;我们也无法调用super.getThemeResId()
方法。如果你真的,真的希望能够有条件地覆盖它并调用超级实现作为后备,你将不得不使用Reflection来获得超级实现的方法:
try {
((Object) this).getClass().getMethod("getThemeResId").invoke(this);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}