Last active
November 24, 2015 07:44
-
-
Save woshidan/e8703ec975d80d01f80c to your computer and use it in GitHub Desktop.
potatotips23_3_points_for_avoid_traps_desgin_support_library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- android.support.design.widget.CollapsingToolbarLayoutのapp:title --> | |
<!-- を指定していないか、空白の場合と、app:titleEnabled="false"の場合はToolbarのtitleが使われる --> | |
<!-- app:titleEnabled="false"だとアニメーションしない --> | |
<android.support.design.widget.CoordinatorLayout | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"> | |
<android.support.design.widget.AppBarLayout | |
android:id="@+id/app_bar" | |
android:layout_width="match_parent" | |
android:layout_height="200dp"> | |
<android.support.design.widget.CollapsingToolbarLayout | |
android:id="@+id/collapsing_toolbar" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
app:title="" | |
app:contentScrim="#fff" | |
app:layout_scrollFlags="scroll|exitUntilCollapsed"> | |
<ImageView | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:background="#26e" | |
android:scaleType="centerCrop" | |
app:layout_collapseMode="parallax"/> | |
<android.support.v7.widget.Toolbar | |
android:id="@+id/tool_bar" | |
app:title="ToolbarTitle" | |
android:layout_width="match_parent" | |
android:layout_height="?attr/actionBarSize" | |
app:layout_collapseMode="pin"/> | |
</android.support.design.widget.CollapsingToolbarLayout> | |
</android.support.design.widget.AppBarLayout> | |
<!-- 見慣れないかもですが、ここはスクロールする要素だったらなんでもよいみたいです --> | |
<android.support.v4.widget.NestedScrollView | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
> | |
<View | |
android:layout_width="match_parent" | |
android:layout_height="2000dp" | |
/> | |
</android.support.v4.widget.NestedScrollView> | |
</android.support.design.widget.CoordinatorLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- * FlotingLabelがTextInputLayoutのものになる --> | |
<!-- * 通常のhintがEditTextのものになる --> | |
<!-- * 入力フォームが空のとき、FloatingLabelと通常のhintの両方が表示されてびびる --> | |
<!-- たぶん通常のonDraw()の後に、 | |
分岐も無くFloatingLabelとして動いている部分のViewの描画処理を呼んでいるせい --> | |
<!-- | |
@Override | |
public void draw(Canvas canvas) { | |
super.draw(canvas); | |
mCollapsingTextHelper.draw(canvas); | |
} | |
--> | |
<android.support.design.widget.TextInputLayout | |
android:layout_width="match_parent" | |
android:layout_height="100dp" | |
android:textColorHint="#0f0" | |
android:hint="TextInputLayoutWrapper" | |
> | |
<EditText | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:textColorHint="#f00" | |
android:hint="TextInputLayoutEditText" | |
/> | |
</android.support.design.widget.TextInputLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Use the EditText's hint colors if we don't have one set | |
if (mDefaultTextColor == null) { | |
mDefaultTextColor = mEditText.getHintTextColors(); | |
} | |
// If we do not have a valid hint, try and retrieve it from the EditText | |
if (TextUtils.isEmpty(mHint)) { | |
setHint(mEditText.getHint()); | |
// Clear the EditText's hint as we will display it ourselves | |
mEditText.setHint(null); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// drawChildrenでも割と目当てのViewがあるか見て処理をしてからデフォの処理を呼び出す、 | |
// というのがあった(CollapsingToolbarLayoutなど)けど、(別のクラスのView等にするために)入れ替えたい要素 | |
// を考える時には、その手前(日本語ならだいたい左上)にある要素を消して入れる必要がある(かそっちの方が早い) | |
// と覚えておけば良いような気がする。 | |
// Toolbar | |
protected void onLayout(boolean changed, int l, int t, int r, int b) { | |
final boolean isRtl = ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL; | |
final int width = getWidth(); | |
final int height = getHeight(); | |
final int paddingLeft = getPaddingLeft(); | |
final int paddingRight = getPaddingRight(); | |
final int paddingTop = getPaddingTop(); | |
final int paddingBottom = getPaddingBottom(); | |
int left = paddingLeft; | |
int right = width - paddingRight; | |
final int[] collapsingMargins = mTempMargins; | |
collapsingMargins[0] = collapsingMargins[1] = 0; | |
// Align views within the minimum toolbar height, if set. | |
final int alignmentHeight = ViewCompat.getMinimumHeight(this); | |
if (shouldLayout(mNavButtonView)) { | |
if (isRtl) { | |
right = layoutChildRight(mNavButtonView, right, collapsingMargins, | |
alignmentHeight); | |
} else { | |
left = layoutChildLeft(mNavButtonView, left, collapsingMargins, | |
alignmentHeight); | |
} | |
} | |
// right/leftは1つ前に指定した要素の右/左端の位置なので、 | |
// 想定している要素が配置されたとして、 | |
// その隣に順に突っ込むという式になっている | |
// つまり間が抜けてても左から順番に詰めて配置されるので | |
// 先に配置された要素を入れ替えたい場合でも後の要素も消す必要がある | |
if (shouldLayout(mCollapseButtonView)) { | |
if (isRtl) { | |
right = layoutChildRight(mCollapseButtonView, right, collapsingMargins, | |
alignmentHeight); | |
} else { | |
left = layoutChildLeft(mCollapseButtonView, left, collapsingMargins, | |
alignmentHeight); | |
} | |
} | |
if (shouldLayout(mMenuView)) { | |
if (isRtl) { | |
left = layoutChildLeft(mMenuView, left, collapsingMargins, | |
alignmentHeight); | |
} else { | |
right = layoutChildRight(mMenuView, right, collapsingMargins, | |
alignmentHeight); | |
} | |
} | |
collapsingMargins[0] = Math.max(0, getContentInsetLeft() - left); | |
collapsingMargins[1] = Math.max(0, getContentInsetRight() - (width - paddingRight - right)); | |
left = Math.max(left, getContentInsetLeft()); | |
right = Math.min(right, width - paddingRight - getContentInsetRight()); | |
if (shouldLayout(mExpandedActionView)) { | |
if (isRtl) { | |
right = layoutChildRight(mExpandedActionView, right, collapsingMargins, | |
alignmentHeight); | |
} else { | |
left = layoutChildLeft(mExpandedActionView, left, collapsingMargins, | |
alignmentHeight); | |
} | |
} | |
if (shouldLayout(mLogoView)) { | |
if (isRtl) { | |
right = layoutChildRight(mLogoView, right, collapsingMargins, | |
alignmentHeight); | |
} else { | |
left = layoutChildLeft(mLogoView, left, collapsingMargins, | |
alignmentHeight); | |
} | |
} | |
final boolean layoutTitle = shouldLayout(mTitleTextView); | |
final boolean layoutSubtitle = shouldLayout(mSubtitleTextView); | |
int titleHeight = 0; | |
if (layoutTitle) { | |
final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams(); | |
titleHeight += lp.topMargin + mTitleTextView.getMeasuredHeight() + lp.bottomMargin; | |
} | |
if (layoutSubtitle) { | |
final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams(); | |
titleHeight += lp.topMargin + mSubtitleTextView.getMeasuredHeight() + lp.bottomMargin; | |
} | |
if (layoutTitle || layoutSubtitle) { | |
int titleTop; | |
final View topChild = layoutTitle ? mTitleTextView : mSubtitleTextView; | |
final View bottomChild = layoutSubtitle ? mSubtitleTextView : mTitleTextView; | |
final LayoutParams toplp = (LayoutParams) topChild.getLayoutParams(); | |
final LayoutParams bottomlp = (LayoutParams) bottomChild.getLayoutParams(); | |
final boolean titleHasWidth = layoutTitle && mTitleTextView.getMeasuredWidth() > 0 | |
|| layoutSubtitle && mSubtitleTextView.getMeasuredWidth() > 0; | |
switch (mGravity & Gravity.VERTICAL_GRAVITY_MASK) { | |
case Gravity.TOP: | |
titleTop = getPaddingTop() + toplp.topMargin + mTitleMarginTop; | |
break; | |
default: | |
case Gravity.CENTER_VERTICAL: | |
final int space = height - paddingTop - paddingBottom; | |
int spaceAbove = (space - titleHeight) / 2; | |
if (spaceAbove < toplp.topMargin + mTitleMarginTop) { | |
spaceAbove = toplp.topMargin + mTitleMarginTop; | |
} else { | |
final int spaceBelow = height - paddingBottom - titleHeight - | |
spaceAbove - paddingTop; | |
if (spaceBelow < toplp.bottomMargin + mTitleMarginBottom) { | |
spaceAbove = Math.max(0, spaceAbove - | |
(bottomlp.bottomMargin + mTitleMarginBottom - spaceBelow)); | |
} | |
} | |
titleTop = paddingTop + spaceAbove; | |
break; | |
case Gravity.BOTTOM: | |
titleTop = height - paddingBottom - bottomlp.bottomMargin - mTitleMarginBottom - | |
titleHeight; | |
break; | |
} | |
if (isRtl) { | |
final int rd = (titleHasWidth ? mTitleMarginStart : 0) - collapsingMargins[1]; | |
right -= Math.max(0, rd); | |
collapsingMargins[1] = Math.max(0, -rd); | |
int titleRight = right; | |
int subtitleRight = right; | |
if (layoutTitle) { | |
final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams(); | |
final int titleLeft = titleRight - mTitleTextView.getMeasuredWidth(); | |
final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight(); | |
mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom); | |
titleRight = titleLeft - mTitleMarginEnd; | |
titleTop = titleBottom + lp.bottomMargin; | |
} | |
if (layoutSubtitle) { | |
final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams(); | |
titleTop += lp.topMargin; | |
final int subtitleLeft = subtitleRight - mSubtitleTextView.getMeasuredWidth(); | |
final int subtitleBottom = titleTop + mSubtitleTextView.getMeasuredHeight(); | |
mSubtitleTextView.layout(subtitleLeft, titleTop, subtitleRight, subtitleBottom); | |
subtitleRight = subtitleRight - mTitleMarginEnd; | |
titleTop = subtitleBottom + lp.bottomMargin; | |
} | |
if (titleHasWidth) { | |
right = Math.min(titleRight, subtitleRight); | |
} | |
} else { | |
final int ld = (titleHasWidth ? mTitleMarginStart : 0) - collapsingMargins[0]; | |
left += Math.max(0, ld); | |
collapsingMargins[0] = Math.max(0, -ld); | |
int titleLeft = left; | |
int subtitleLeft = left; | |
if (layoutTitle) { | |
final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams(); | |
final int titleRight = titleLeft + mTitleTextView.getMeasuredWidth(); | |
final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight(); | |
mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom); | |
titleLeft = titleRight + mTitleMarginEnd; | |
titleTop = titleBottom + lp.bottomMargin; | |
} | |
if (layoutSubtitle) { | |
final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams(); | |
titleTop += lp.topMargin; | |
final int subtitleRight = subtitleLeft + mSubtitleTextView.getMeasuredWidth(); | |
final int subtitleBottom = titleTop + mSubtitleTextView.getMeasuredHeight(); | |
mSubtitleTextView.layout(subtitleLeft, titleTop, subtitleRight, subtitleBottom); | |
subtitleLeft = subtitleRight + mTitleMarginEnd; | |
titleTop = subtitleBottom + lp.bottomMargin; | |
} | |
if (titleHasWidth) { | |
left = Math.max(titleLeft, subtitleLeft); | |
} | |
} | |
} | |
// Get all remaining children sorted for layout. This is all prepared | |
// such that absolute layout direction can be used below. | |
addCustomViewsWithGravity(mTempViews, Gravity.LEFT); | |
final int leftViewsCount = mTempViews.size(); | |
for (int i = 0; i < leftViewsCount; i++) { | |
left = layoutChildLeft(mTempViews.get(i), left, collapsingMargins, | |
alignmentHeight); | |
} | |
addCustomViewsWithGravity(mTempViews, Gravity.RIGHT); | |
final int rightViewsCount = mTempViews.size(); | |
for (int i = 0; i < rightViewsCount; i++) { | |
right = layoutChildRight(mTempViews.get(i), right, collapsingMargins, | |
alignmentHeight); | |
} | |
// Centered views try to center with respect to the whole bar, but views pinned | |
// to the left or right can push the mass of centered views to one side or the other. | |
addCustomViewsWithGravity(mTempViews, Gravity.CENTER_HORIZONTAL); | |
final int centerViewsWidth = getViewListMeasuredWidth(mTempViews, collapsingMargins); | |
final int parentCenter = paddingLeft + (width - paddingLeft - paddingRight) / 2; | |
final int halfCenterViewsWidth = centerViewsWidth / 2; | |
int centerLeft = parentCenter - halfCenterViewsWidth; | |
final int centerRight = centerLeft + centerViewsWidth; | |
if (centerLeft < left) { | |
centerLeft = left; | |
} else if (centerRight > right) { | |
centerLeft -= centerRight - right; | |
} | |
final int centerViewsCount = mTempViews.size(); | |
for (int i = 0; i < centerViewsCount; i++) { | |
centerLeft = layoutChildLeft(mTempViews.get(i), centerLeft, collapsingMargins, | |
alignmentHeight); | |
} | |
mTempViews.clear(); | |
} | |
// InputTextLayout | |
@Override | |
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { | |
super.onLayout(changed, left, top, right, bottom); | |
if (mEditText != null) { | |
final int l = mEditText.getLeft() + mEditText.getCompoundPaddingLeft(); | |
final int r = mEditText.getRight() - mEditText.getCompoundPaddingRight(); | |
mCollapsingTextHelper.setExpandedBounds(l, | |
mEditText.getTop() + mEditText.getCompoundPaddingTop(), | |
r, mEditText.getBottom() - mEditText.getCompoundPaddingBottom()); | |
// Set the collapsed bounds to be the the full height (minus padding) to match the | |
// EditText's editable area | |
mCollapsingTextHelper.setCollapsedBounds(l, getPaddingTop(), | |
r, bottom - top - getPaddingBottom()); | |
mCollapsingTextHelper.recalculate(); | |
} | |
} | |
// CollapsingToolbarLayout | |
@Override | |
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { | |
super.onLayout(changed, left, top, right, bottom); | |
// Update our child view offset helpers | |
for (int i = 0, z = getChildCount(); i < z; i++) { | |
final View child = getChildAt(i); | |
if (mLastInsets != null && !ViewCompat.getFitsSystemWindows(child)) { | |
final int insetTop = mLastInsets.getSystemWindowInsetTop(); | |
if (child.getTop() < insetTop) { | |
// If the child isn't set to fit system windows but is drawing within the inset | |
// offset it down | |
child.offsetTopAndBottom(insetTop); | |
} | |
} | |
getViewOffsetHelper(child).onViewLayout(); | |
} | |
// Update the collapsed bounds by getting it's transformed bounds | |
if (mCollapsingTitleEnabled && mDummyView != null) { | |
ViewGroupUtils.getDescendantRect(this, mDummyView, mTmpRect); | |
mCollapsingTextHelper.setCollapsedBounds(mTmpRect.left, bottom - mTmpRect.height(), | |
mTmpRect.right, bottom); | |
// Update the expanded bounds | |
mCollapsingTextHelper.setExpandedBounds( | |
mExpandedMarginLeft, | |
mTmpRect.bottom + mExpandedMarginTop, | |
right - left - mExpandedMarginRight, | |
bottom - top - mExpandedMarginBottom); | |
mCollapsingTextHelper.recalculate(); | |
} | |
// Finally, set our minimum height to enable proper AppBarLayout collapsing | |
if (mToolbar != null) { | |
if (mCollapsingTitleEnabled && TextUtils.isEmpty(mCollapsingTextHelper.getText())) { | |
// If we do not currently have a title, try and grab it from the Toolbar | |
mCollapsingTextHelper.setText(mToolbar.getTitle()); | |
} | |
setMinimumHeight(mToolbar.getHeight()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// CollapsingToolbarLayoutの場合 | |
private void animateScrim(int targetAlpha) { | |
ensureToolbar(); | |
if (mScrimAnimator == null) { | |
mScrimAnimator = ViewUtils.createAnimator(); | |
mScrimAnimator.setDuration(SCRIM_ANIMATION_DURATION); | |
mScrimAnimator.setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR); | |
mScrimAnimator.setUpdateListener(new ValueAnimatorCompat.AnimatorUpdateListener() { | |
@Override | |
public void onAnimationUpdate(ValueAnimatorCompat animator) { | |
setScrimAlpha(animator.getAnimatedIntValue()); | |
} | |
}); | |
} else if (mScrimAnimator.isRunning()) { | |
mScrimAnimator.cancel(); | |
} | |
mScrimAnimator.setIntValues(mScrimAlpha, targetAlpha); | |
mScrimAnimator.start(); | |
} | |
// InputTextLayoutの場合 | |
private static final int ANIMATION_DURATION = 200; | |
private void collapseHint(boolean animate) { | |
if (mAnimator != null && mAnimator.isRunning()) { | |
mAnimator.cancel(); | |
} | |
if (animate && mHintAnimationEnabled) { | |
animateToExpansionFraction(1f); | |
} else { | |
mCollapsingTextHelper.setExpansionFraction(1f); | |
} | |
} | |
private void animateToExpansionFraction(final float target) { | |
if (mCollapsingTextHelper.getExpansionFraction() == target) { | |
return; | |
} | |
if (mAnimator == null) { | |
mAnimator = ViewUtils.createAnimator(); | |
mAnimator.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR); | |
mAnimator.setDuration(ANIMATION_DURATION); | |
mAnimator.setUpdateListener(new ValueAnimatorCompat.AnimatorUpdateListener() { | |
@Override | |
public void onAnimationUpdate(ValueAnimatorCompat animator) { | |
mCollapsingTextHelper.setExpansionFraction(animator.getAnimatedFloatValue()); | |
} | |
}); | |
} | |
mAnimator.setFloatValues(mCollapsingTextHelper.getExpansionFraction(), target); | |
mAnimator.start(); | |
} |
Author
woshidan
commented
Nov 24, 2015
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment