安卓中是否有可能对一个视图进行遮罩处理?

23

是否可以遮盖视图?例如,如果我的设计需要在椭圆形开口处可见一个列表视图。有没有办法为视图创建一个蒙版?它被称为其他什么吗?因为在Android文档中找到的所有关于遮罩的引用都是在讨论如何遮罩画布对象或可绘制对象。但我认为将交互对象(如列表视图)制作成可绘制对象并不是一种好方法。这只是目前需要处理的限制吗?

2个回答

40

是的,你可以 - 你需要覆盖你的视图的绘制方法 - 例如:

......
final Path path = new Path();
path.addRoundRect(new RectF(0,0,getWidth(),getHeight()),10,10,Direction.CW);
......
@Override
protected void dispatchDraw(Canvas canvas){
    canvas.clipPath(path);
    super.dispatchDraw(canvas);
}

这将只在路径设置的边界内绘制您的视图。


1
你也可以创建任何你想要的“遮罩”效果,然后将其放入自己的视图中,并将其放在所需视图的顶部/前面。如果你只需要这个效果用于一个特定的视图,那么这将节省你创建自己的视图和编辑绘制方法的麻烦。 - FoamyGuy
那样做是完全错误的,Tim。在性能至关重要的移动平台上创建完全不必要的视图层次结构会降低您的应用程序速度。 - asenovm
我同意这会导致更差的性能。但我认为,如果他只是将其应用于一个活动中的一个视图,那么在现有设备上,人眼无法察觉到性能差异。而且,使用单独的视图可能对某些人来说比尝试创建自己的视图并覆盖绘制方法要容易得多。我知道,做这样的事情在你掌握了一些技巧之后就变得微不足道了。但如果你以前从未这样做过,对我来说似乎有点令人生畏。 - FoamyGuy
如果我使用以下代码覆盖ImageView的dispatchDraw方法,什么也不会发生。图像将像以前一样被绘制。 - Janusz
这是因为ImageView不是ViewGroup。您需要通过使用与上面相同的代码覆盖onDraw方法来解决此问题。 - asenovm
6
该解决方案无法用于隐藏动画视图。 - Tommy Sadiq Hinrichsen

14

是的,你甚至可以遮盖完整的布局。 无耻的自我宣传。

<com.christophesmet.android.views.maskableframelayout.MaskableFrameLayout
android:id="@+id/frm_mask_animated"
android:layout_width="100dp"
app:porterduffxfermode="DST_IN"
app:mask="@drawable/animation_mask"
android:layout_height="100dp">

<ImageView android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:scaleType="centerCrop"
           android:src="@drawable/unicorn"/>

你可以在这里找到它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接