OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chrome.browser.ntp; |
| 6 |
| 7 import android.content.Context; |
| 8 import android.util.AttributeSet; |
| 9 import android.view.View; |
| 10 |
| 11 import com.google.android.apps.chrome.R; |
| 12 |
| 13 import org.chromium.chrome.browser.widget.BoundedLinearLayout; |
| 14 |
| 15 /** |
| 16 * Layout for the new tab page. This positions the page elements in the correct
vertical positions. |
| 17 * There are no separate phone and tablet UIs; this layout adapts based on the a
vailable space. |
| 18 */ |
| 19 public class NewTabPageLayout extends BoundedLinearLayout { |
| 20 |
| 21 // Space permitting, the spacers will grow from 0dp to the heights given bel
ow. If there is |
| 22 // additional space, it will be distributed evenly between the top and botto
m spacers. |
| 23 private static final float TOP_SPACER_HEIGHT_DP = 44f; |
| 24 private static final float MIDDLE_SPACER_HEIGHT_DP = 24f; |
| 25 private static final float BOTTOM_SPACER_HEIGHT_DP = 44f; |
| 26 private static final float TOTAL_SPACER_HEIGHT_DP = TOP_SPACER_HEIGHT_DP |
| 27 + MIDDLE_SPACER_HEIGHT_DP + BOTTOM_SPACER_HEIGHT_DP; |
| 28 |
| 29 private final int mTopSpacerHeight; |
| 30 private final int mMiddleSpacerHeight; |
| 31 private final int mBottomSpacerHeight; |
| 32 private final int mTotalSpacerHeight; |
| 33 |
| 34 private int mParentScrollViewportHeight; |
| 35 |
| 36 private View mTopSpacer; |
| 37 private View mMiddleSpacer; |
| 38 private View mBottomSpacer; |
| 39 private View mScrollCompensationSpacer; |
| 40 |
| 41 /** |
| 42 * Constructor for inflating from XML. |
| 43 */ |
| 44 public NewTabPageLayout(Context context, AttributeSet attrs) { |
| 45 super(context, attrs); |
| 46 float density = getResources().getDisplayMetrics().density; |
| 47 mTopSpacerHeight = Math.round(density * TOP_SPACER_HEIGHT_DP); |
| 48 mMiddleSpacerHeight = Math.round(density * MIDDLE_SPACER_HEIGHT_DP); |
| 49 mBottomSpacerHeight = Math.round(density * BOTTOM_SPACER_HEIGHT_DP); |
| 50 mTotalSpacerHeight = Math.round(density * TOTAL_SPACER_HEIGHT_DP); |
| 51 } |
| 52 |
| 53 @Override |
| 54 protected void onFinishInflate() { |
| 55 super.onFinishInflate(); |
| 56 mTopSpacer = findViewById(R.id.ntp_top_spacer); |
| 57 mMiddleSpacer = findViewById(R.id.ntp_middle_spacer); |
| 58 mBottomSpacer = findViewById(R.id.ntp_bottom_spacer); |
| 59 mScrollCompensationSpacer = findViewById(R.id.ntp_scroll_spacer); |
| 60 } |
| 61 |
| 62 /** |
| 63 * Specifies the height of the scroll viewport for the container view of thi
s View. |
| 64 * |
| 65 * <p> |
| 66 * As this is required in onMeasure, we can not rely on the parent having th
e proper |
| 67 * size set yet and thus must be told explicitly of this size. |
| 68 * |
| 69 * @param height The height of the scroll viewport containing this view. |
| 70 */ |
| 71 public void setParentScrollViewportHeight(int height) { |
| 72 mParentScrollViewportHeight = height; |
| 73 } |
| 74 |
| 75 @Override |
| 76 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
| 77 mScrollCompensationSpacer.getLayoutParams().height = 0; |
| 78 super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
| 79 distributeExtraSpace(mTopSpacer.getMeasuredHeight()); |
| 80 |
| 81 int minScrollAmountRequired = 0; |
| 82 for (int i = 0; i < getChildCount(); i++) { |
| 83 View child = getChildAt(i); |
| 84 |
| 85 MarginLayoutParams layoutParams = (MarginLayoutParams) child.getLayo
utParams(); |
| 86 if (child.getVisibility() != View.GONE) { |
| 87 minScrollAmountRequired += layoutParams.topMargin; |
| 88 } |
| 89 |
| 90 if (child.getId() == R.id.most_visited_layout) break; |
| 91 if (child.getId() == R.id.opt_out_promo) break; |
| 92 |
| 93 if (child.getVisibility() != View.GONE) { |
| 94 minScrollAmountRequired += child.getMeasuredHeight(); |
| 95 minScrollAmountRequired += layoutParams.bottomMargin; |
| 96 } |
| 97 } |
| 98 |
| 99 int scrollVsHeightDiff = getMeasuredHeight() - mParentScrollViewportHeig
ht; |
| 100 if (getMeasuredHeight() > mParentScrollViewportHeight |
| 101 && scrollVsHeightDiff < minScrollAmountRequired) { |
| 102 mScrollCompensationSpacer.getLayoutParams().height = |
| 103 minScrollAmountRequired - scrollVsHeightDiff; |
| 104 mScrollCompensationSpacer.setVisibility(View.INVISIBLE); |
| 105 |
| 106 super.onMeasure(widthMeasureSpec, heightMeasureSpec); |
| 107 distributeExtraSpace(mTopSpacer.getMeasuredHeight()); |
| 108 } else { |
| 109 mScrollCompensationSpacer.setVisibility(View.GONE); |
| 110 } |
| 111 } |
| 112 |
| 113 /** |
| 114 * Distribute extra vertical space between the three spacer views. |
| 115 * @param extraHeight The amount of extra space, in pixels. |
| 116 */ |
| 117 private void distributeExtraSpace(int extraHeight) { |
| 118 int topSpacerHeight; |
| 119 int middleSpacerHeight; |
| 120 int bottomSpacerHeight; |
| 121 |
| 122 if (extraHeight < mTotalSpacerHeight) { |
| 123 topSpacerHeight = Math.round(extraHeight |
| 124 * (TOP_SPACER_HEIGHT_DP / TOTAL_SPACER_HEIGHT_DP)); |
| 125 extraHeight -= topSpacerHeight; |
| 126 middleSpacerHeight = Math.round(extraHeight * (MIDDLE_SPACER_HEIGHT_
DP |
| 127 / (MIDDLE_SPACER_HEIGHT_DP + BOTTOM_SPACER_HEIGHT_DP))); |
| 128 extraHeight -= middleSpacerHeight; |
| 129 bottomSpacerHeight = extraHeight; |
| 130 } else { |
| 131 topSpacerHeight = mTopSpacerHeight; |
| 132 middleSpacerHeight = mMiddleSpacerHeight; |
| 133 bottomSpacerHeight = mBottomSpacerHeight; |
| 134 extraHeight -= mTotalSpacerHeight; |
| 135 |
| 136 // Distribute remaining space evenly between the top and bottom spac
ers. |
| 137 topSpacerHeight += (extraHeight + 1) / 2; |
| 138 bottomSpacerHeight += extraHeight / 2; |
| 139 } |
| 140 |
| 141 int widthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY); |
| 142 mTopSpacer.measure(widthSpec, |
| 143 MeasureSpec.makeMeasureSpec(topSpacerHeight, MeasureSpec.EXACTLY
)); |
| 144 mMiddleSpacer.measure(widthSpec, |
| 145 MeasureSpec.makeMeasureSpec(middleSpacerHeight, MeasureSpec.EXAC
TLY)); |
| 146 mBottomSpacer.measure(widthSpec, |
| 147 MeasureSpec.makeMeasureSpec(bottomSpacerHeight, MeasureSpec.EXAC
TLY)); |
| 148 } |
| 149 } |
OLD | NEW |