Возможным решением было бы расширить используемый макет, переопределить его метод drawChild()
, а затем применить пользовательский canvas.clipPath()
перед вызовом super.drawChild()
.Ниже я добавил быстрый прототип для такого решения.
Что делает PartiallyTransparentLayout:
- Запретить любые дочерние представления, независимо от их кода рисования,
- изрисуя внутри области, указанной указанным путем
- , вместо этого покажите все, что находится за макетом.
Чего он не делает:
- Удалите дочерние представления из структуры ввода.Это означает, что все входные события отправляются как обычно, даже для полностью невидимых представлений.
Это, безусловно, можно отнести к решению типа взлома, нет гарантии, что оно будет работать в будущих версияхрамки.Я также не уверен в производительности этого решения при работе с более сложной иерархией представлений.Вам следует рассмотреть возможность аннулирования только той части макета, которая была затронута изменением обтравочного контура.
Дайте мне знать, если я неправильно понял ваши требования.
РЕДАКТИРОВАТЬ: я только что заметил, чтонекоторые анимации материала будут по-прежнему отображаться внутри обтравочного контура.
MainActivity.java
Используется только для OnClickListener
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onClick(View v) {
PartiallyTransparentLayout layout = findViewById(R.id.magic_layout);
final int maxWidth = layout.getWidth();
final int maxHeight = layout.getHeight();
Path p = new Path();
p.moveTo((float) (Math.random() * maxWidth), (float) (Math.random() * maxHeight));
p.lineTo((float) (Math.random() * maxWidth), (float) (Math.random() * maxHeight));
p.lineTo((float) (Math.random() * maxWidth), (float) (Math.random() * maxHeight));
p.close();
layout.setClipping(p);
}
}
PartiallyTransparentLayout.java
Здесь происходит вся магия
public class PartiallyTransparentLayout extends ConstraintLayout {
private Path clipPath = null;
public PartiallyTransparentLayout(Context c) {
super(c);
}
public PartiallyTransparentLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PartiallyTransparentLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// Intercept the drawChild call and set a custom clipping for all following drawing operations
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
// Our clipPath specifies the area we are NOT allowed to draw in, inversing the clipping
// is different on higher Android versions.
if (clipPath != null) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
canvas.clipOutPath(clipPath);
} else {
canvas.clipPath(clipPath, Region.Op.DIFFERENCE);
}
}
// Let the framework continue as if nothing happened.
return super.drawChild(canvas, child, drawingTime);
}
// Specify the custom clipping
public void setClipping(Path p) {
clipPath = p;
// Every time the clip changes, every view needs to redraw to account for it.
invalidate();
}
}
activity_main.xml
В основном содержит несколько случайных представлений для целей тестирования.
<?xml version="1.0" encoding="utf-8"?>
<com.example.transparent_viewgroup_test.PartiallyTransparentLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/magic_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView3"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:cropToPadding="false"
android:padding="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@android:color/holo_red_dark" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textColor="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.191"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.48" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:text="TextView"
android:textColor="@android:color/white"
app:layout_constraintBottom_toTopOf="@+id/imageView2"
app:layout_constraintStart_toStartOf="@+id/imageView2" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="96dp"
android:text="Button"
android:onClick="onClick"
app:layout_constraintBottom_toTopOf="@+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<ImageView
android:id="@+id/imageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="76dp"
android:layout_marginLeft="76dp"
android:layout_marginTop="12dp"
android:src="@android:color/black"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="148dp"
android:layout_marginLeft="148dp"
android:src="@android:color/black"
app:layout_constraintStart_toEndOf="@+id/imageView"
app:layout_constraintTop_toTopOf="@+id/imageView" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="34dp"
android:text="TextView"
app:layout_constraintStart_toStartOf="@+id/switch1"
app:layout_constraintTop_toBottomOf="@+id/switch1" />
<Switch
android:id="@+id/switch1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="17dp"
android:layout_marginRight="17dp"
android:text="Switch"
app:layout_constraintBottom_toTopOf="@+id/textView2"
app:layout_constraintEnd_toStartOf="@+id/textView2" />
<ImageView
android:id="@+id/imageView4"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="87dp"
android:layout_marginBottom="86dp"
app:layout_constraintBottom_toBottomOf="@+id/imageView3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView2"
app:srcCompat="@android:color/holo_orange_light" />
</com.example.transparent_viewgroup_test.PartiallyTransparentLayout>