SnackbarContentLayout.java revision fa0f82f629bf95681c14ed559922f77a3030aa18
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package android.support.design.internal; 17 18import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; 19 20import android.content.Context; 21import android.content.res.TypedArray; 22import android.support.annotation.RestrictTo; 23import android.support.design.R; 24import android.support.design.widget.BaseTransientBottomBar; 25import android.support.v4.view.ViewCompat; 26import android.util.AttributeSet; 27import android.view.View; 28import android.widget.Button; 29import android.widget.LinearLayout; 30import android.widget.TextView; 31 32/** 33 * @hide 34 */ 35@RestrictTo(LIBRARY_GROUP) 36public class SnackbarContentLayout extends LinearLayout implements 37 BaseTransientBottomBar.ContentViewCallback { 38 private TextView mMessageView; 39 private Button mActionView; 40 41 private int mMaxWidth; 42 private int mMaxInlineActionWidth; 43 44 public SnackbarContentLayout(Context context) { 45 this(context, null); 46 } 47 48 public SnackbarContentLayout(Context context, AttributeSet attrs) { 49 super(context, attrs); 50 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SnackbarLayout); 51 mMaxWidth = a.getDimensionPixelSize(R.styleable.SnackbarLayout_android_maxWidth, -1); 52 mMaxInlineActionWidth = a.getDimensionPixelSize( 53 R.styleable.SnackbarLayout_maxActionInlineWidth, -1); 54 a.recycle(); 55 } 56 57 @Override 58 protected void onFinishInflate() { 59 super.onFinishInflate(); 60 mMessageView = (TextView) findViewById(R.id.snackbar_text); 61 mActionView = (Button) findViewById(R.id.snackbar_action); 62 } 63 64 public TextView getMessageView() { 65 return mMessageView; 66 } 67 68 public Button getActionView() { 69 return mActionView; 70 } 71 72 @Override 73 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 74 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 75 76 if (mMaxWidth > 0 && getMeasuredWidth() > mMaxWidth) { 77 widthMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxWidth, MeasureSpec.EXACTLY); 78 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 79 } 80 81 final int multiLineVPadding = getResources().getDimensionPixelSize( 82 R.dimen.design_snackbar_padding_vertical_2lines); 83 final int singleLineVPadding = getResources().getDimensionPixelSize( 84 R.dimen.design_snackbar_padding_vertical); 85 final boolean isMultiLine = mMessageView.getLayout().getLineCount() > 1; 86 87 boolean remeasure = false; 88 if (isMultiLine && mMaxInlineActionWidth > 0 89 && mActionView.getMeasuredWidth() > mMaxInlineActionWidth) { 90 if (updateViewsWithinLayout(VERTICAL, multiLineVPadding, 91 multiLineVPadding - singleLineVPadding)) { 92 remeasure = true; 93 } 94 } else { 95 final int messagePadding = isMultiLine ? multiLineVPadding : singleLineVPadding; 96 if (updateViewsWithinLayout(HORIZONTAL, messagePadding, messagePadding)) { 97 remeasure = true; 98 } 99 } 100 101 if (remeasure) { 102 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 103 } 104 } 105 106 private boolean updateViewsWithinLayout(final int orientation, 107 final int messagePadTop, final int messagePadBottom) { 108 boolean changed = false; 109 if (orientation != getOrientation()) { 110 setOrientation(orientation); 111 changed = true; 112 } 113 if (mMessageView.getPaddingTop() != messagePadTop 114 || mMessageView.getPaddingBottom() != messagePadBottom) { 115 updateTopBottomPadding(mMessageView, messagePadTop, messagePadBottom); 116 changed = true; 117 } 118 return changed; 119 } 120 121 private static void updateTopBottomPadding(View view, int topPadding, int bottomPadding) { 122 if (ViewCompat.isPaddingRelative(view)) { 123 ViewCompat.setPaddingRelative(view, 124 ViewCompat.getPaddingStart(view), topPadding, 125 ViewCompat.getPaddingEnd(view), bottomPadding); 126 } else { 127 view.setPadding(view.getPaddingLeft(), topPadding, 128 view.getPaddingRight(), bottomPadding); 129 } 130 } 131 132 @Override 133 public void animateContentIn(int delay, int duration) { 134 mMessageView.setAlpha(0f); 135 mMessageView.animate().alpha(1f).setDuration(duration) 136 .setStartDelay(delay).start(); 137 138 if (mActionView.getVisibility() == VISIBLE) { 139 mActionView.setAlpha(0f); 140 mActionView.animate().alpha(1f).setDuration(duration) 141 .setStartDelay(delay).start(); 142 } 143 } 144 145 @Override 146 public void animateContentOut(int delay, int duration) { 147 mMessageView.setAlpha(1f); 148 mMessageView.animate().alpha(0f).setDuration(duration) 149 .setStartDelay(delay).start(); 150 151 if (mActionView.getVisibility() == VISIBLE) { 152 mActionView.setAlpha(1f); 153 mActionView.animate().alpha(0f).setDuration(duration) 154 .setStartDelay(delay).start(); 155 } 156 } 157} 158