I have a ConstraintLayout with clipsChildren=false property, since some of the children need to draw outside of their bounds. One of the children (View A) however should be clipped (I'm using a LinearGradient, if that matters). I cannot move the child view to a different parent, as it is constrained to a sibling view (View B) that needs to draw outside the bounds.
How can I force just View A to be clipped, without also clipping View B?
I have attempted disablind clipsChildren on parent during onDraw in View A, but to no success. I've also tried manually setting clipRect on canvas, but even without changes the clipRect is being set to the size of View A.
You will have to do your own clipping on the view that should be clipped. For the ConstraintLayout set android:clipChildren="false".
Write a custom view that extends the type of view that you want to clip. Change the draw() method to something like the following to clip any part of the view that falls outside of the parent.
In the image below, the four corners of the large red square are occupied with text views that are clipped. You can see the outline of the full text views in the following image. The top center purple square is child that is not clipped.

Here is the custom view that is used:
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()
}
}
...and the XML for the layout:
<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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With