Как сделать только часть моего макета (включая частичные виды) невидимой на основе координат? - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть макет, который я хочу, чтобы только его части были невидимыми, в зависимости от координат, которые я предоставил.Это будет означать, что некоторые виды в моем макете будут частично невидимы (например, если координаты покрывают только часть вида, но не все).Это возможно?Какие методы вы бы мне посоветовали?Спасибо!

Ответы [ 3 ]

0 голосов
/ 08 февраля 2019

Это технически невозможно, если вы:

  • Создаете свои собственные пользовательские виды

  • Делайте некоторые хитрости

Как правило, самый простой подход - это хитрая часть, но это также зависит от того, что вы подразумеваете под невидимым.

Например, общий способ сделать часть представления невидимым - это просто создать цветной вид с тем же цветом, что и фон действия.Затем вы помещаете этот вид поверх тех частей других видов, которые вы хотите сделать «невидимыми».Эффект будет таким же, как если бы были видны только части представления, а другие невидимы.

0 голосов
/ 09 февраля 2019

Возможным решением было бы расширить используемый макет, переопределить его метод drawChild(), а затем применить пользовательский canvas.clipPath() перед вызовом super.drawChild().Ниже я добавил быстрый прототип для такого решения.

Что делает PartiallyTransparentLayout:

  • Запретить любые дочерние представления, независимо от их кода рисования,
  • изрисуя внутри области, указанной указанным путем
  • , вместо этого покажите все, что находится за макетом.

Чего он не делает:

  • Удалите дочерние представления из структуры ввода.Это означает, что все входные события отправляются как обычно, даже для полностью невидимых представлений.

Это, безусловно, можно отнести к решению типа взлома, нет гарантии, что оно будет работать в будущих версияхрамки.Я также не уверен в производительности этого решения при работе с более сложной иерархией представлений.Вам следует рассмотреть возможность аннулирования только той части макета, которая была затронута изменением обтравочного контура.

Дайте мне знать, если я неправильно понял ваши требования.

РЕДАКТИРОВАТЬ: я только что заметил, чтонекоторые анимации материала будут по-прежнему отображаться внутри обтравочного контура.

Prototype screenshot

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>
0 голосов
/ 08 февраля 2019
view.setVisibility(INVISIBLE)

А если вы хотите изменить видимость группы видов, поместите их в группу видов и установите для видимости группы видимость НЕВИДИМ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...