如何一次性否定视图的颜色?
How do I negate color of views in one go?
在问这个问题之前,我已经对此进行了一些研究,也在 SO 上寻找了类似的问题,其中 none 似乎回答了它。
我计划在我的 android 应用程序中提供 视觉辅助功能 功能,用户可以一次性取消 UI 的颜色(让我们说一个简单的按钮来否定颜色)。
虽然很少有例外。很少有视图(比如操作栏)的颜色最好固定,即使用户选择否定颜色,以提高可读性。
我能想到几个选项来实现同样的效果:
- 维护每个布局的两个副本xml - 一个具有正常彩色视图,一个具有否定彩色视图。现在,每当用户选择否定颜色时,只需在 java.
中加载相应的 xml
- 在color.xml中维护每个视图颜色的两个副本。在两个不同的主题下定义它们。现在根据用户需要设置相应的主题。
挑战:
可扩展性:鉴于该应用程序已经使用了数百个视图,数百个 XML,并且它将在未来的更新中使用越来越多的视图,我该如何采取关心那个?
问题:
1. 考虑到可扩展性,哪个选项更好。
2.有没有其他方法可以做到这一点?
3. 是否有 android API 给出视图的否定颜色?
在我看来,最好的方法是在您的应用程序中维护一个正常主题和一个否定主题,然后根据用户设置,在运行时更改主题。
这种方法有一个问题,那就是您必须在 activity 中 setContentView
之前 setTheme
。这意味着您无法在用户单击按钮后立即反映更改。话虽这么说,但在我看来,这是最好的解决方案,因为它可以很好地扩展,并且您可能拥有一个 BaseActivity,您的所有 Activites 都继承自该 BaseActivity,可以检查设置您的主题。
setTheme(userBlackTheme? android.R.style.Theme_Dark : android.R.style.Theme_Light);
super.onCreate(savedInstanceState); //IMPORTANT: setTheme is before the super call!!!
setContentView(R.layout.main);
如果您在屏幕上有一个按钮并且想要这样做,那么您应该能够换掉视图上的所有样式属性并将它们替换为深色属性。这意味着,虽然您不会更改主题,但您可以将每个视图的属性更改为深色主题的属性。
然后您将不得不递归循环遍历所有视图,并根据视图的 class 将其属性更改为 Dark/Light。
public void recursiveLoopChildren(ViewGroup parent) {
for (int i = parent.getChildCount() - 1; i >= 0; i--) {
final View child = parent.getChildAt(i);
if (child instanceof ViewGroup) {
((ViewGroup) child).setBackgroundColor(useDarkTheme? Color.BLACK : Color.WHITE);
recursiveLoopChildren((ViewGroup) child);
// DO SOMETHING WITH VIEWGROUP, AFTER CHILDREN HAS BEEN LOOPED
} else {
if (child instanceof TextView) {
((TextView) child).setTextColor(...);
}
}
}
}
简而言之,您可能想要实现这两个选项,当您单击更改主题按钮时,选项 1 所有新活动都将使用深色主题,选项 2 将更改您当前的 activity .或者...当单击更改主题的按钮时,重新加载当前的 activity,对用户而言不是那么优雅,也许您可以重新加载相同的 activity 并使用深色主题并将其淡入上方浅色主题,然后在浅色主题上调用 finish()
,在简化您的生活的同时提供良好的过渡。希望这有帮助。
在问这个问题之前,我已经对此进行了一些研究,也在 SO 上寻找了类似的问题,其中 none 似乎回答了它。
我计划在我的 android 应用程序中提供 视觉辅助功能 功能,用户可以一次性取消 UI 的颜色(让我们说一个简单的按钮来否定颜色)。
虽然很少有例外。很少有视图(比如操作栏)的颜色最好固定,即使用户选择否定颜色,以提高可读性。
我能想到几个选项来实现同样的效果:
- 维护每个布局的两个副本xml - 一个具有正常彩色视图,一个具有否定彩色视图。现在,每当用户选择否定颜色时,只需在 java. 中加载相应的 xml
- 在color.xml中维护每个视图颜色的两个副本。在两个不同的主题下定义它们。现在根据用户需要设置相应的主题。
挑战:
可扩展性:鉴于该应用程序已经使用了数百个视图,数百个 XML,并且它将在未来的更新中使用越来越多的视图,我该如何采取关心那个?
问题:
1. 考虑到可扩展性,哪个选项更好。
2.有没有其他方法可以做到这一点?
3. 是否有 android API 给出视图的否定颜色?
在我看来,最好的方法是在您的应用程序中维护一个正常主题和一个否定主题,然后根据用户设置,在运行时更改主题。
这种方法有一个问题,那就是您必须在 activity 中 setContentView
之前 setTheme
。这意味着您无法在用户单击按钮后立即反映更改。话虽这么说,但在我看来,这是最好的解决方案,因为它可以很好地扩展,并且您可能拥有一个 BaseActivity,您的所有 Activites 都继承自该 BaseActivity,可以检查设置您的主题。
setTheme(userBlackTheme? android.R.style.Theme_Dark : android.R.style.Theme_Light);
super.onCreate(savedInstanceState); //IMPORTANT: setTheme is before the super call!!!
setContentView(R.layout.main);
如果您在屏幕上有一个按钮并且想要这样做,那么您应该能够换掉视图上的所有样式属性并将它们替换为深色属性。这意味着,虽然您不会更改主题,但您可以将每个视图的属性更改为深色主题的属性。
然后您将不得不递归循环遍历所有视图,并根据视图的 class 将其属性更改为 Dark/Light。
public void recursiveLoopChildren(ViewGroup parent) {
for (int i = parent.getChildCount() - 1; i >= 0; i--) {
final View child = parent.getChildAt(i);
if (child instanceof ViewGroup) {
((ViewGroup) child).setBackgroundColor(useDarkTheme? Color.BLACK : Color.WHITE);
recursiveLoopChildren((ViewGroup) child);
// DO SOMETHING WITH VIEWGROUP, AFTER CHILDREN HAS BEEN LOOPED
} else {
if (child instanceof TextView) {
((TextView) child).setTextColor(...);
}
}
}
}
简而言之,您可能想要实现这两个选项,当您单击更改主题按钮时,选项 1 所有新活动都将使用深色主题,选项 2 将更改您当前的 activity .或者...当单击更改主题的按钮时,重新加载当前的 activity,对用户而言不是那么优雅,也许您可以重新加载相同的 activity 并使用深色主题并将其淡入上方浅色主题,然后在浅色主题上调用 finish()
,在简化您的生活的同时提供良好的过渡。希望这有帮助。