三种实现夜间模式的方法
夜间模式阅读功能在移动客户端上应用非常广泛,这里总结了三种夜间模式的实现方式,供参考。
方法一、在白天模式的视图上盖一张半透明黑色图片。
夜间模式最主要是为了保护眼睛,档光,不刺眼。透明度不一定是50%,Alpha可以取0.75(25%透明)。
在原视图的之上覆盖一张图片,或者背景色="#BF000000"的视图。唯一需要注意的是要把屏幕事件传递给下层视图。
//覆盖在视图顶部的View的颜色
public static Color TopBackgroundColorDay = Color.FromArgb(0, 0, 0, 0); //Colors.Transparent 全透明
public static Color TopBackgroundColorNight = Color.FromArgb(191, 0, 0, 0); //alpha=0.75, 25%透明黑
用户调整显示模式时,直接修改背景色就轻易实现了白天模式与夜间模式的转换:
ShowModeView.Background.SetValue(SolidColorBrush.ColorProperty, ColorDefines.TopBackgroundColorNight);
此方法对各个平台都是可以实现的,只是API有差别而已。当内容视图的呈现区域发生变化时,视图的大小可能会发生变化,这个时候要调整ShowModeView的大小,始终与视图区域保持重合。
方法二、显示模式发生变化时重新构造视图。
只需要设置好预定值,在显示模式发生变化时重新构造视图,使用新预定值构造出视图即可。构造出的视图可以恢复原来的选中状态、偏移量等。
此方法的优点是逻辑清晰,重新构造时可以对每个呈现细节进行调整,缺点是在有些手机上屏幕会快速闪一下。
方法三、显示模式发生变化时逐一调整视图各个UIElement属性。
使用设置好的预定值给视图的UI元素赋值即可。
这种方法需要对构造过程非常熟悉,优点是不需要覆盖额外的视图,也不需要重新构造,过渡效果非常平稳,不过对于动态创建的UI实现起来稍复杂:
public static void ContentShowModeChanged(ListBox listBox, ENightMode nightMode)
{
Color txtClr = ColorDefines.TextColorDay;
double imageBlockOpacity = ColorDefines.ImageOpacityDay;
……
if (nightMode == ENightMode.ENightMode)
{
txtClr = ColorDefines.TextColorNight;
imageBlockOpacity = ColorDefines.ImageOpacityNight;
……
}
UIElement ue = null;
for (int i = 1; i < listBox.Items.Count; i++)
{
ue = listBox.Items[i] as UIElement;
if (ue != null)
{
Type typ = ue.GetType();
switch (typ.Name)
{
case "TextBlock":
case "HyperlinkButton":
PropertyInfo sb = yp.GetProperty("Foreground"); //取属性
sb.SetValue(ue, foreGround, null); //给属性设置新值
break;
case "CanvasWithBorder":
(ue as CanvasWithBorder).Background.SetValue(ImageBrush.OpacityProperty, imageBlockOpacity);
break;
case "Canvas":
{
Canvas canvas = ue as Canvas;
……
}
break;
case "StackPanel":
{
List<RichTextBox> lstRtb = ControlOpt.GetVisualChildCollection<RichTextBox>(ue);
for (int j = 0; j < lstRtb.Count; j++)
{
lstRtb[j].Foreground.SetValue(SolidColorBrush.ColorProperty, txtClr);
}
}
break;
……
}
}
}
}