public class

Placeholder

extends View

 java.lang.Object

↳View

↳androidx.constraintlayout.widget.Placeholder

Gradle dependencies

compile group: 'androidx.constraintlayout', name: 'constraintlayout', version: '2.2.0-beta01'

  • groupId: androidx.constraintlayout
  • artifactId: constraintlayout
  • version: 2.2.0-beta01

Artifact androidx.constraintlayout:constraintlayout:2.2.0-beta01 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.constraintlayout:constraintlayout com.android.support.constraint:constraint-layout

Androidx class mapping:

androidx.constraintlayout.widget.Placeholder android.support.constraint.Placeholder

Overview

Added in 1.1

A Placeholder provides a virtual object which can position an existing object.

When the id of another view is set on a placeholder (using setContent()), the placeholder effectively becomes the content view. If the content view exist on the screen it is treated as gone from its original location.

The content view is positioned using the layout of the parameters of the Placeholder (the Placeholder is simply constrained in the layout like any other view).

Summary

Constructors
publicPlaceholder(Context context)

publicPlaceholder(Context context, AttributeSet attrs)

publicPlaceholder(Context context, AttributeSet attrs, int defStyleAttr)

publicPlaceholder(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)

Methods
public ViewgetContent()

Returns the content view

public intgetEmptyVisibility()

Returns the behaviour of a placeholder when it contains no view.

public voidonDraw(Canvas canvas)

Placeholder does not draw anything itself - therefore Paint and Rect allocations are fine to suppress and ignore.

public voidsetContentId(int id)

Sets the content view id

public voidsetEmptyVisibility(int visibility)

Sets the visibility of placeholder when not containing objects typically gone or invisible.

public voidupdatePostMeasure(ConstraintLayout container)

public voidupdatePreLayout(ConstraintLayout container)

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public Placeholder(Context context)

public Placeholder(Context context, AttributeSet attrs)

public Placeholder(Context context, AttributeSet attrs, int defStyleAttr)

public Placeholder(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)

Methods

public int getEmptyVisibility()

Returns the behaviour of a placeholder when it contains no view.

Returns:

Either View.VISIBLE, View.INVISIBLE, View.GONE. Default is INVISIBLE

public void setEmptyVisibility(int visibility)

Sets the visibility of placeholder when not containing objects typically gone or invisible. This can be important as it affects behaviour of surrounding components.

Parameters:

visibility: Either View.VISIBLE, View.INVISIBLE, View.GONE

public View getContent()

Returns the content view

Returns:

null if no content is set, otherwise the content view

public void onDraw(Canvas canvas)

Placeholder does not draw anything itself - therefore Paint and Rect allocations are fine to suppress and ignore.

Parameters:

canvas:

public void updatePreLayout(ConstraintLayout container)

Parameters:

container:

public void setContentId(int id)

Sets the content view id

Parameters:

id: the id of the content view we want to place in the Placeholder

public void updatePostMeasure(ConstraintLayout container)

Parameters:

container:

Source

/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.constraintlayout.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.constraintlayout.core.widgets.ConstraintWidget;

/**
 * <b>Added in 1.1</b>
 * <p>
 * A {@code Placeholder} provides a virtual object which can position an existing object.
 * <p>
 * When the id of another view is set on a placeholder (using {@code setContent()}),
 * the placeholder effectively becomes the content view. If the content view exist on the
 * screen it is treated as gone from its original location.
 * <p>
 * The content view is positioned using the layout of the parameters of the
 * {@code Placeholder}  (the {@code Placeholder}
 * is simply constrained in the layout like any other view).
 * </p>
 */
public class Placeholder extends View {

    private int mContentId = -1;
    private View mContent = null;
    private int mEmptyVisibility = View.INVISIBLE;

    public Placeholder(Context context) {
        super(context);
        init(null);
    }

    public Placeholder(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public Placeholder(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    public Placeholder(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        super.setVisibility(mEmptyVisibility);
        mContentId = -1;
        if (attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs,
                    R.styleable.ConstraintLayout_placeholder);
            final int count = a.getIndexCount();
            for (int i = 0; i < count; i++) {
                int attr = a.getIndex(i);
                if (attr == R.styleable.ConstraintLayout_placeholder_content) {
                    mContentId = a.getResourceId(attr, mContentId);
                } else {
                    if (attr == R.styleable
                            .ConstraintLayout_placeholder_placeholder_emptyVisibility) {
                        mEmptyVisibility = a.getInt(attr, mEmptyVisibility);
                    }
                }
            }
            a.recycle();
        }
    }

    /**
     * Returns the behaviour of a placeholder when it contains no view.
     *
     * @return Either View.VISIBLE, View.INVISIBLE, View.GONE. Default is INVISIBLE
     */
    public int getEmptyVisibility() {
        return mEmptyVisibility;
    }

    /**
     * Sets the visibility of placeholder when not containing objects typically gone or invisible.
     * This can be important as it affects behaviour of surrounding components.
     *
     * @param visibility Either View.VISIBLE, View.INVISIBLE, View.GONE
     */
    public void setEmptyVisibility(int visibility) {
        mEmptyVisibility = visibility;
    }

    /**
     * Returns the content view
     *
     * @return {@code null} if no content is set, otherwise the content view
     */
    public View getContent() {
        return mContent;
    }

    /**
     * Placeholder does not draw anything itself - therefore Paint and Rect allocations
     * are fine to suppress and ignore.
     *
     * @param canvas
     *
     */
    @Override
    public void onDraw(@NonNull Canvas canvas) {
        if (isInEditMode()) {
            canvas.drawRGB(223, 223, 223);

            @SuppressLint("DrawAllocation")
            Paint paint = new Paint();
            paint.setARGB(255, 210, 210, 210);
            paint.setTextAlign(Paint.Align.CENTER);
            paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));

            @SuppressLint("DrawAllocation")
            Rect r = new Rect();
            canvas.getClipBounds(r);
            paint.setTextSize(r.height());
            int cHeight = r.height();
            int cWidth = r.width();
            paint.setTextAlign(Paint.Align.LEFT);
            String text = "?";
            paint.getTextBounds(text, 0, text.length(), r);
            float x = cWidth / 2f - r.width() / 2f - r.left;
            float y = cHeight / 2f + r.height() / 2f - r.bottom;
            canvas.drawText(text, x, y, paint);
        }
    }

    /**
     * @param container
     *
     */
    public void updatePreLayout(ConstraintLayout container) {
        if (mContentId == -1) {
            if (!isInEditMode()) {
                setVisibility(mEmptyVisibility);
            }
        }

        mContent = container.findViewById(mContentId);
        if (mContent != null) {
            ConstraintLayout.LayoutParams layoutParamsContent =
                    (ConstraintLayout.LayoutParams) mContent.getLayoutParams();
            layoutParamsContent.mIsInPlaceholder = true;
            mContent.setVisibility(View.VISIBLE);
            setVisibility(View.VISIBLE);
        }
    }

    /**
     * Sets the content view id
     *
     * @param id the id of the content view we want to place in the Placeholder
     */
    public void setContentId(int id) {
        if (mContentId == id) {
            return;
        }
        if (mContent != null) {
            mContent.setVisibility(VISIBLE); // ???
            ConstraintLayout.LayoutParams layoutParamsContent =
                    (ConstraintLayout.LayoutParams) mContent.getLayoutParams();
            layoutParamsContent.mIsInPlaceholder = false;
            mContent = null;
        }

        mContentId = id;
        if (id != ConstraintLayout.LayoutParams.UNSET) {
            View v = ((View) getParent()).findViewById(id);
            if (v != null) {
                v.setVisibility(GONE);
            }
        }
    }

    /**
     * @param container
     *
     */
    public void updatePostMeasure(ConstraintLayout container) {
        if (mContent == null) {
            return;
        }
        ConstraintLayout.LayoutParams layoutParams =
                (ConstraintLayout.LayoutParams) getLayoutParams();
        ConstraintLayout.LayoutParams layoutParamsContent = (ConstraintLayout.LayoutParams) mContent
                .getLayoutParams();
        layoutParamsContent.mWidget.setVisibility(View.VISIBLE);
        if (layoutParams.mWidget.getHorizontalDimensionBehaviour()
                != ConstraintWidget.DimensionBehaviour.FIXED) {
            layoutParams.mWidget.setWidth(layoutParamsContent.mWidget.getWidth());
        }
        if (layoutParams.mWidget.getVerticalDimensionBehaviour()
                != ConstraintWidget.DimensionBehaviour.FIXED) {
            layoutParams.mWidget.setHeight(layoutParamsContent.mWidget.getHeight());
        }
        layoutParamsContent.mWidget.setVisibility(View.GONE);
    }
}