| /* |
| * 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 android.support.constraint; |
| |
| 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; |
| |
| /** |
| * <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 N = a.getIndexCount(); |
| for (int i = 0; i < N; 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_emptyVisibility) { |
| mEmptyVisibility = a.getInt(attr, 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 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; |
| } |
| |
| |
| /** |
| * Returns the content view |
| * @return {@code null} if no content is set, otherwise the content view |
| */ |
| public View getContent() { |
| return mContent; |
| } |
| |
| /** |
| * @hide |
| * @param canvas |
| */ |
| public void onDraw(Canvas canvas) { |
| if (isInEditMode()) { |
| canvas.drawRGB(223, 223, 223); |
| Paint paint = new Paint(); |
| paint.setARGB(255, 210, 210, 210); |
| paint.setTextAlign(Paint.Align.CENTER); |
| paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)); |
| |
| 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); |
| } |
| } |
| |
| /** |
| * @hide |
| * @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.isInPlaceholder = 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.isInPlaceholder = false; |
| mContent = null; |
| } |
| |
| mContentId = id; |
| if (id != ConstraintLayout.LayoutParams.UNSET) { |
| View v = ((View) getParent()).findViewById(id); |
| if (v != null) { |
| v.setVisibility(GONE); |
| } |
| } |
| } |
| |
| /** |
| * @hide |
| * @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.widget.setVisibility(View.VISIBLE); |
| layoutParams.widget.setWidth(layoutParamsContent.widget.getWidth()); |
| layoutParams.widget.setHeight(layoutParamsContent.widget.getHeight()); |
| layoutParamsContent.widget.setVisibility(View.GONE); |
| } |
| |
| } |