Bug 1317446 - 3. Add TabStripDividerItem for TabStripView dividers and spacing. r=sebastian

MozReview-Commit-ID: 5OC58tEGQrM

--HG--
extra : rebase_source : 50272cc5990fa3fb409a103575a2ff739daf825e
extra : source : 542d785801381ce681377c4dbb27b43edd7cdbd7
This commit is contained in:
Tom Klein 2016-10-16 21:03:50 -05:00
Родитель 87f9e0dca6
Коммит 04ab70169c
5 изменённых файлов: 144 добавлений и 2 удалений

Просмотреть файл

@ -0,0 +1,90 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.tabs;
import org.mozilla.gecko.R;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.View;
class TabStripDividerItem extends RecyclerView.ItemDecoration {
private final int margin;
private final int dividerWidth;
private final int dividerHeight;
private final int dividerPaddingBottom;
private final Paint dividerPaint;
TabStripDividerItem(Context context) {
margin = (int) context.getResources().getDimension(R.dimen.tablet_tab_strip_item_margin);
dividerWidth = (int) context.getResources().getDimension(R.dimen.tablet_tab_strip_divider_width);
dividerHeight = (int) context.getResources().getDimension(R.dimen.tablet_tab_strip_divider_height);
dividerPaddingBottom = (int) context.getResources().getDimension(R.dimen.tablet_tab_strip_divider_padding_bottom);
dividerPaint = new Paint();
dividerPaint.setColor(ContextCompat.getColor(context, R.color.tablet_tab_strip_divider_color));
dividerPaint.setStyle(Paint.Style.FILL_AND_STROKE);
}
/**
* Return whether a divider should be drawn on the left side of the tab represented by
* {@code view}.
*/
private static boolean drawLeftDividerForView(View view, RecyclerView parent) {
final int position = parent.getChildAdapterPosition(view);
// No left divider if this is tab 0 or this tab is currently pressed.
if (position == 0 || view.isPressed()) {
return false;
}
final int selectedPosition = ((TabStripView) parent).getPositionForSelectedTab();
// No left divider if this tab or the previous tab is the current selected tab.
if (selectedPosition != RecyclerView.NO_POSITION &&
(position == selectedPosition || position == selectedPosition + 1)) {
return false;
}
final RecyclerView.ViewHolder holder = parent.findViewHolderForAdapterPosition(position - 1);
// No left divider if the previous tab is currently pressed.
if (holder != null && holder.itemView.isPressed()) {
return false;
}
return true;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
final int position = parent.getChildAdapterPosition(view);
final int leftOffset = position == 0 ? 0 : margin;
final int rightOffset = position == parent.getAdapter().getItemCount() - 1 ? 0 : margin;
outRect.set(leftOffset, 0, rightOffset, 0);
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
final int childCount = parent.getChildCount();
if (childCount == 0) {
return;
}
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
if (drawLeftDividerForView(child, parent)) {
final float left = child.getLeft() + child.getTranslationX() + Math.abs(margin);
final float top = child.getTop() + child.getTranslationY();
final float dividerTop = top + child.getHeight() - dividerHeight - dividerPaddingBottom;
final float dividerBottom = dividerTop + dividerHeight;
c.drawRect(left - dividerWidth, dividerTop, left, dividerBottom, dividerPaint);
}
}
}
}

Просмотреть файл

@ -51,6 +51,8 @@ public class TabStripView extends RecyclerView {
animatorListener = new TabAnimatorListener();
setChildrenDrawingOrderEnabled(true);
adapter = new TabStripAdapter(context);
setAdapter(adapter);
@ -60,7 +62,7 @@ public class TabStripView extends RecyclerView {
setItemAnimator(new TabStripItemAnimator(ANIM_TIME_MS));
// TODO add item decoration.
addItemDecoration(new TabStripDividerItem(context));
}
/* package */ void refreshTabs() {
@ -124,8 +126,12 @@ public class TabStripView extends RecyclerView {
adapter.notifyTabChanged(tab);
}
public int getPositionForSelectedTab() {
return adapter.getPositionForTab(Tabs.getInstance().getSelectedTab());
}
private void updateSelectedPosition() {
final int selected = adapter.getPositionForTab(Tabs.getInstance().getSelectedTab());
final int selected = getPositionForSelectedTab();
if (selected != -1) {
scrollToPosition(selected);
}
@ -150,6 +156,45 @@ public class TabStripView extends RecyclerView {
child.setTranslationY(0);
}
/**
* Return the position of the currently selected tab relative to the tabs currently visible in
* the tabs list, or -1 if the currently selected tab isn't visible in the tabs list.
*/
private int getRelativeSelectedPosition(int visibleTabsCount) {
final int selectedPosition = getPositionForSelectedTab();
final LinearLayoutManager layoutManager = (LinearLayoutManager) getLayoutManager();
final int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
final int relativeSelectedPosition = selectedPosition - firstVisiblePosition;
if (relativeSelectedPosition < 0 || relativeSelectedPosition > visibleTabsCount - 1) {
return -1;
}
return relativeSelectedPosition;
}
@Override
protected int getChildDrawingOrder(int childCount, int i) {
final int relativeSelectedPosition = getRelativeSelectedPosition(childCount);
if (relativeSelectedPosition == -1) {
// The selected tab isn't visible, so we don't need to adjust drawing order.
return i;
}
// Explanation of the input parameters: there are childCount tabs visible, and right now
// we're returning which of those tabs to draw i'th, for some i between 0 and
// childCount - 1.
if (i == childCount - 1) {
// Draw the selected tab last.
return relativeSelectedPosition;
} else if (i >= relativeSelectedPosition) {
// Draw the tabs after the selected tab one iteration earlier than normal.
return i + 1;
} else {
// Draw the tabs before the selected tab in their normal order.
return i;
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);

Просмотреть файл

@ -855,6 +855,7 @@ if max_sdk_version >= 11:
gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [
'tabs/TabStrip.java',
'tabs/TabStripAdapter.java',
'tabs/TabStripDividerItem.java',
'tabs/TabStripItemAnimator.java',
'tabs/TabStripItemView.java',
'tabs/TabStripView.java'

Просмотреть файл

@ -145,4 +145,6 @@
<color name="activity_stream_timestamp">#FFD3D3D3</color>
<color name="activity_stream_icon">#FF919191</color>
<color name="tablet_tab_strip_divider_color">#555555</color>
</resources>

Просмотреть файл

@ -43,6 +43,10 @@
<dimen name="tablet_tab_strip_height">48dp</dimen>
<dimen name="tablet_tab_strip_item_width">208dp</dimen>
<dimen name="tablet_tab_strip_fading_edge_size">15dp</dimen>
<dimen name="tablet_tab_strip_item_margin">-14dp</dimen>
<dimen name="tablet_tab_strip_divider_width">1dp</dimen>
<dimen name="tablet_tab_strip_divider_height">30dp</dimen>
<dimen name="tablet_tab_strip_divider_padding_bottom">6dp</dimen>
<dimen name="tablet_browser_toolbar_menu_item_width">56dp</dimen>
<!-- Padding combines with an 18dp image to form the menu item width and height. -->
<dimen name="tablet_browser_toolbar_menu_item_padding_horizontal">19dp</dimen>