Android 9(API 级别 28)及更高版本中提供放大镜微件,这是一个虚拟放大镜,通过代表镜头的叠加窗格来显示所选视图的放大副本。此功能可改善文本插入和选择方面的用户体验:将放大镜应用于文本时,用户可以通过查看窗格内随其手指移动的放大文本来精确定位光标或选择手柄。下面的图 1 展示了放大镜帮助选择文本的方式。放大镜 API 并非与文本关联,并且此微件可用于各种用例,例如读取小号字体或者放大地图上看不太清楚的地名。

放大镜已与 TextView、EditText 或 WebView 等平台微件集成。它可在各种应用上提供一致的文本操纵体验。该微件附带一个简单的 API,可用于根据应用的上下文放大任何 View。

dab69714e51cc46a85ae57f447bfe822.png

图 1. 放大文本。当用户抓取正确的选择手柄后,系统会弹出放大镜来帮助准确定位。

API 用法

放大镜能够以编程方式用于任意视图,如下所示:

Kotlin

val view: View = findViewById(R.id.view)

val magnifier = Magnifier(view)

magnifier.show(view.width / 2.0f, view.height / 2.0f)Java

View view = findViewById(R.id.view);

Magnifier magnifier = new Magnifier(view);

magnifier.show(view.getWidth() / 2, view.getHeight() / 2);

假设视图层次结构已有第一个布局,放大镜会显示在屏幕上,并包含一个以视图内给定坐标为中心的区域。该窗格会出现在要复制的内容的中心点上方。放大镜会持续显示,直到用户将其关闭为止。

注意:show() 的参数是相对于被放大的视图左上角而言。

假设我们想要更改放大的视图的背景:

Kotlin

view.setBackgroundColor(...)Java

view.setBackgroundColor(...);

假设背景颜色在放大镜中可见,放大镜的内容现已过时,因为系统仍显示使用旧背景的视图区域。如需刷新内容,请使用 update() 方法:

Kotlin

view.post { magnifier.update() }Java

view.post(new Runnable() {

magnifier.update();

});

注意:我们发布了更新操作,以确保在执行该操作时,系统已绘制使用新背景颜色的视图。这是因为放大镜内容始终比放大的视图晚一帧。

完成后,通过调用 dismiss() 方法关闭放大镜:

Kotlin

magnifier.dismiss()Java

magnifier.dismiss();

在用户互动时放大

放大镜的一个常见用例是让用户能够通过触摸来放大某个视图区域,如下面的图 2 所示。为实现此功能,您可以根据视图接收到的触摸事件来更新放大镜:

Kotlin

imageView.setOnTouchListener { v, event ->

when (event.actionMasked) {

MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {

val viewPosition = IntArray(2)

v.getLocationOnScreen(viewPosition)

magnifier.show(event.rawX - viewPosition[0], event.rawY - viewPosition[1])

}

MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {

magnifier.dismiss()

}

}

true

}Java

imageView.setOnTouchListener(new View.OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

switch (event.getActionMasked()) {

case MotionEvent.ACTION_DOWN:

// Fall through.

case MotionEvent.ACTION_MOVE: {

final int[] viewPosition = new int[2];

v.getLocationOnScreen(viewPosition);

magnifier.show(event.getRawX() - viewPosition[0],

event.getRawY() - viewPosition[1]);

break;

}

case MotionEvent.ACTION_CANCEL:

// Fall through.

case MotionEvent.ACTION_UP: {

magnifier.dismiss();

}

}

return true;

}

});

注意:即使视图包含在可滚动的容器中且部分被遮盖,放大镜也绝不会显示不属于该视图的放大内容。当传递给 show() 的坐标暗示要复制外部内容时,它们会被强制转换到视图的可见区域内。

20f113b247a4c6c6b199d92df10b166f.gif

图 2. 放大镜随用户的触摸移动。它应用于 ViewGroup,其中左侧包含一个 ImageView,右侧包含一个 TextView。

放大文本时的其他注意事项

对于平台文本微件,请务必了解具体的放大镜行为,并在整个 Android 平台以一致的方式为您的自定义文本视图启用放大镜。请注意以下几点:

当用户抓取插入或选择手柄时,会立即触发放大镜。

在水平方向,放大镜始终顺畅地随用户手指移动,而在垂直方向,放大镜则固定在当前文本行的中心。

水平移动时,放大镜仅在当前行的左右边界之间移动。此外,如果用户的手指离开左右边界,并且手指触摸位置与最近边界之间的水平距离大于放大镜内容原始宽度的一半,系统会关闭放大镜,因为光标在放大镜内将不再可见。

如果文本字体过大,那么绝不会触发放大镜。具体而言,如果文本字体的下缘与上缘之间的距离大于放入放大镜的内容的高度,此文本就会被视为过大。在这种情况下,触发放大镜没有什么助益。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐