我有一个带有clipsChildren=false属性的ConstraintLayout,因为某些子项需要在其边界之外绘制。但是,应该修剪其中一个孩子(视图A)(如果重要的话,我使用的是LinearGradient)。我无法将子视图移动到其他父视图,因为它受限于需要在边界外绘制的同级视图(视图B)。

如何强制只剪切视图A而又不剪切视图B?

我曾尝试在View A的onDraw期间使父项上的clipsChildren异常,但未成功。我也尝试过在画布上手动设置clipRect,但是即使没有更改,clipRect也被设置为View A的大小。

最佳答案

您将必须对应该剪切的视图进行剪切。为ConstraintLayout设置android:clipChildren="false"

编写一个自定义视图,以扩展您要裁剪的视图的类型。将draw()方法更改为类似于以下内容的内容,以裁剪掉父视图之外的视图的任何部分。

在下图中,大红色正方形的四个角被剪切的文本视图占据。您可以在下图中看到全文视图的轮廓。顶部中间的紫色正方形是未修剪的子级。

android - 在clipsChildren = false父项的单个子项上启用剪辑-LMLPHP

这是使用的自定义视图:

class ClippedChild @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : TextView(context, attrs, defStyleAttr) {
    override fun draw(canvas: Canvas) {
        val parent = parent as ViewGroup
        val clippingRect = Rect()
        getDrawingRect(clippingRect)

        if (left < 0) {
            clippingRect.left = -left
  }
        if (top < 0) {
            clippingRect.top = -top
  }
        if (right > parent.width) {
            clippingRect.right = width - (right - parent.width)
        }
        if (bottom > parent.height) {
            clippingRect.bottom = height - (bottom - parent.height)
        }
        canvas.save()
        canvas.clipRect(clippingRect)
        super.draw(canvas)
        canvas.restore()
    }
}


...以及布局的XML:

 <androidx.constraintlayout.widget.ConstraintLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:clipChildren="false"
      tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
  android:id="@+id/innerLayout"
  android:layout_width="250dp"
  android:layout_height="250dp"
  android:background="#F44336"
  app:layout_constraintBottom_toBottomOf="parent"
  app:layout_constraintEnd_toEndOf="parent"
  app:layout_constraintStart_toStartOf="parent"
  app:layout_constraintTop_toTopOf="parent">

        <View
  android:id="@+id/ViewA"
  android:layout_width="100dp"
  android:layout_height="100dp"
  android:background="#9C27B0"
  app:layout_constraintBottom_toTopOf="parent"
  app:layout_constraintEnd_toEndOf="parent"
  app:layout_constraintStart_toStartOf="parent"
  app:layout_constraintTop_toTopOf="parent" />

        <com.example.myapplication.ClippedChild
  android:id="@+id/ViewB1"
  android:layout_width="100dp"
  android:layout_height="100dp"
  android:background="#9C27B0"
  android:text="top\n/start"
  android:gravity="bottom|end"
  app:layout_constraintTop_toTopOf="parent"
  app:layout_constraintBottom_toTopOf="parent"
  app:layout_constraintStart_toStartOf="parent"
  app:layout_constraintEnd_toStartOf="parent" />

        <com.example.myapplication.ClippedChild
  android:id="@+id/ViewB2"
  android:layout_width="100dp"
  android:layout_height="100dp"
  android:text="top\n/end"
  android:gravity="bottom|start"
  android:background="#2196F3"
  app:layout_constraintTop_toTopOf="parent"
  app:layout_constraintBottom_toTopOf="parent"
  app:layout_constraintStart_toEndOf="parent"
  app:layout_constraintEnd_toEndOf="parent" />

        <com.example.myapplication.ClippedChild
  android:id="@+id/ViewB3"
  android:layout_width="100dp"
  android:layout_height="100dp"
  android:background="#8BC34A"
  android:text="bottom\n/end"
  android:gravity="top|start"
  app:layout_constraintBottom_toBottomOf="parent"
  app:layout_constraintEnd_toEndOf="parent"
  app:layout_constraintStart_toEndOf="parent"
  app:layout_constraintTop_toBottomOf="parent" />

        <com.example.myapplication.ClippedChild
  android:id="@+id/ViewB4"
  android:layout_width="100dp"
  android:layout_height="100dp"
  android:background="#FFEB3B"
  android:text="bottom\n/start"
  android:gravity="top|end"
  app:layout_constraintBottom_toBottomOf="parent"
  app:layout_constraintEnd_toStartOf="parent"
  app:layout_constraintStart_toStartOf="parent"
  app:layout_constraintTop_toBottomOf="parent" />

        <com.example.myapplication.ClippedChild
  android:id="@+id/ViewB5"
  android:layout_width="100dp"
  android:layout_height="100dp"
  android:background="#FFEB3B"
  app:layout_constraintBottom_toBottomOf="parent"
  app:layout_constraintStart_toStartOf="parent"
  app:layout_constraintEnd_toEndOf="parent"
  app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

07-25 22:42