/** * Sets the tab's title. * * @param title * The title, which should be set, as an instance of the type {@link CharSequence}. The * title may neither be null, nor empty */ public final void setTitle(@NonNull final CharSequence title) { Condition.INSTANCE.ensureNotNull(title, "The title may not be null"); Condition.INSTANCE.ensureNotEmpty(title, "The title may not be empty"); this.title = title; notifyOnTitleChanged(); }
@Override public final void setTabPreviewFadeDuration(final long duration) { Condition.INSTANCE.ensureAtLeast(duration, 0, "The duration must be at least 0"); this.tabPreviewFadeDuration = duration; }
/** * Creates a new handler, which can be managed by a {@link TouchEventDispatcher} in order to * dispatch touch events to it. * * @param priority * The priority of the handler as an {@link Integer} value. The priority must be at * least {@link AbstractTouchEventHandler#MIN_PRIORITY} and at maximum {@link * AbstractTouchEventHandler#MAX_PRIORITY} * @param tabSwitcher * The tab switcher, the event handler belongs to, as an instance of the class {@link * TabSwitcher}. The tab switcher may not be null * @param dragThreshold * The threshold of the drag helper, which is used to recognize drag gestures, in pixels * as an {@link Integer} value The threshold must be at least 0 */ public AbstractTouchEventHandler(final int priority, @NonNull final TabSwitcher tabSwitcher, final int dragThreshold) { Condition.INSTANCE.ensureAtLeast(priority, MIN_PRIORITY, "The priority must be at least" + MIN_PRIORITY); Condition.INSTANCE.ensureAtMaximum(priority, MAX_PRIORITY, "The priority must be at maximum " + MAX_PRIORITY); Condition.INSTANCE.ensureNotNull(tabSwitcher, "The tab switcher may not be null"); Condition.INSTANCE.ensureAtLeast(dragThreshold, 0, "The drag threshold must be at least 0"); this.priority = priority; this.tabSwitcher = tabSwitcher; this.dragHelper = new DragHelper(0); this.dragThreshold = dragThreshold; reset(); }
@NonNull final AttachedViewRecycler<AbstractItem, ?> viewRecycler, @NonNull final Tab[] array, final int firstIndex) { Condition.INSTANCE.ensureNotNull(model, "The model may not be null"); Condition.INSTANCE.ensureNotNull(viewRecycler, "The view recycler may not be null"); Condition.INSTANCE.ensureNotNull(array, "The array may not be null"); Condition.INSTANCE.ensureAtLeast(firstIndex, 0, "The first index must be at least 0"); this.model = model; this.viewRecycler = viewRecycler;
/** * Sets the bounds of the onscreen area, which should be taken into consideration for * recognizing the drag gestures, which are create by the builder. drag gestures. * * @param left * The coordinate of the left edge in pixels as a {@link Float} value. The * coordinate must be at least 0 * @param top * The coordinate of the top edge in pixels as a {@link Float} value. The coordinate * must be at least 0 * @param right * The coordinate of the right edge in pixels as a {@link Float} value. The * coordinate must be greater than the coordinate of the left edge * @param bottom * The coordinate of the bottom edge in pixels as a {@link Float} value. The * coordinate must be greater than the coordinate of the top edge * @return The builder, this method has been called upon, as an instance of the generic type * BuilderType. The builder may not be null */ @NonNull public final BuilderType setTouchableArea(final float left, final float top, final float right, final float bottom) { Condition.INSTANCE.ensureAtLeast(left, 0, "The left coordinate must be at least 0"); Condition.INSTANCE.ensureAtLeast(top, 0, "The top coordinate must be at least 0"); Condition.INSTANCE.ensureGreater(right, left, "The right coordinate must be greater than " + left); Condition.INSTANCE.ensureGreater(bottom, top, "The bottom coordinate must be greater than " + top); return setTouchableArea(new RectF(left, top, right, bottom)); }
/** * Sets the alpha, which should be used by the animation. * * @param alpha * The alpha, which should be set, as a {@link Float} value. The alpha must be at least * 0 and at maximum 1 */ protected final void setAlpha(final float alpha) { Condition.INSTANCE.ensureAtLeast(alpha, 0, "The alpha must be at least 0"); Condition.INSTANCE.ensureAtMaximum(alpha, 1, "The alpha must be at maximum 1"); this.alpha = alpha; }
/** * Returns the adapter, which allows to inflate the views, which are associated with tabs. * * @return The adapter, which allows to inflate the views, which are associated with tabs, as an * instance of the class {@link ContentRecyclerAdapter} */ public final ContentRecyclerAdapter getContentRecyclerAdapter() { Condition.INSTANCE.ensureNotNull(contentRecyclerAdapter, "No decorator has been set", IllegalStateException.class); return contentRecyclerAdapter; }
/** * Creates a new item. * * @param id * The item's id as an {@link Integer} value. The id must be at least 0 * @param title * The item's title as an instance of the type {@link CharSequence}. The title may * neither be null, nor empty */ public Item(final int id, @NonNull final CharSequence title) { super(id, title); Condition.INSTANCE.ensureAtLeast(id, 0, "The id must be at least 0"); Condition.INSTANCE.ensureNotNull(title, "The title may not be null"); Condition.INSTANCE.ensureNotEmpty(title, "The title may not be empty"); this.icon = null; this.enabled = true; }
/** * Creates a new scrollable area. * * @param top * The top-most area, which should be scrollable, as a value of the enum {@link Area} or * null, if no area should be scrollable * @param bottom * The bottom-most area, which should be scrollable, as a value of the enum {@link * Area}. If the top-most area is null, the bottom-most are must be null as well. The * index of the bottom-most area must be at least the index of the top-most area */ private ScrollableArea(final Area top, final Area bottom) { if (top != null) { Condition.INSTANCE.ensureNotNull(bottom, "If the top-most area is not null, the bottom-most area may neither be null"); Condition.INSTANCE.ensureAtLeast(bottom.getIndex(), top.getIndex(), "The index of the bottom-most area must be at least the index of the top-most area"); } else { Condition.INSTANCE.ensureTrue(bottom == null, "If the top-most area is null, the bottom-most area must be null as well"); } this.topScrollableArea = top; this.bottomScrollableArea = bottom; }
@Override public final int getTabSwitcherPadding(@NonNull final Axis axis, final int gravity) { Condition.INSTANCE.ensureNotNull(axis, "The axis may not be null"); Condition.INSTANCE .ensureTrue(gravity == Gravity.START || gravity == Gravity.END, "Invalid gravity"); if (axis == Axis.DRAGGING_AXIS) { return gravity == Gravity.START ? getTabSwitcher().getPaddingLeft() : getTabSwitcher().getPaddingRight(); } else { return gravity == Gravity.START ? getTabSwitcher().getPaddingTop() : getTabSwitcher().getPaddingBottom(); } }
/** * Creates a new scroll listener, which allows to animate a view to become hidden or shown * depending on the observed list view's scrolling direction. * * @param view * The view, which should be animated by the listener, as an instance of the class * {@link View}. The view may not be null * @param direction * The direction, which should be be used to translate the view in order to hide it, as * a value of the enum {@link Direction}. The direction may either be <code>UP</code> * or * <code>DOWN</code> * @param animationDuration * The duration of the animation, which is used to show or hide the view, in * milliseconds as a {@link Long} value. The duration must be greater than 0 */ public HideViewOnScrollAnimation(@NonNull final View view, @NonNull final Direction direction, final long animationDuration) { Condition.INSTANCE.ensureNotNull(view, "The view may not be null"); Condition.INSTANCE.ensureNotNull(direction, "The direction may not be null"); Condition.INSTANCE.ensureGreater(animationDuration, 0, "The animation duration must be greater than 0"); this.animatedView = view; this.direction = direction; this.animationDuration = animationDuration; this.listeners = new ListenerList<>(); }
/** * Sets the symbol, which should be used to separate floating point numbers for textual * representation. * * @param floatingPointSeparator * The symbol, which should be set, as an instance of the type {@link CharSequence} or * null, if the default symbol should be used. The length of the symbol must be 1 */ public final void setFloatingPointSeparator( @Nullable final CharSequence floatingPointSeparator) { if (floatingPointSeparator != null) { Condition.INSTANCE.ensureAtMaximum(floatingPointSeparator.length(), 1, "The floating point separator's length must be 1"); } this.floatingPointSeparator = floatingPointSeparator; }
@Override public final void onAllTabsAdded(final int index, @NonNull final Tab[] tabs, final int previousSelectedTabIndex, final int selectedTabIndex, final boolean selectionChanged, @NonNull final Animation animation) { Condition.INSTANCE.ensureTrue(animation instanceof SwipeAnimation, animation.getClass().getSimpleName() + " not supported for adding multiple tabs"); getLogger().logInfo(getClass(), "Added " + tabs.length + " tabs at index " + index + " using a " + animation.getClass().getSimpleName()); addAllTabs(index, tabs, animation); }
/** * Creates a new layout listener, which encapsulates another listener, which is notified, * when the listener has been invoked a specific number of times. * * @param count * The number of times, the listener should be invoked until the encapsulated * listener is notified, as an {@link Integer} value. The count must be greater than * 0 * @param listener * The encapsulated listener, which should be notified, when the listener has been * notified the given number of times, as an instance of the type {@link * OnGlobalLayoutListener} or null, if no listener should be notified */ CompoundLayoutListener(final int count, @Nullable final OnGlobalLayoutListener listener) { Condition.INSTANCE.ensureGreater(count, 0, "The count must be greater than 0"); this.count = count; this.listener = listener; }
/** * Sets the elevation of the button bar, which is shown when using the activity as a wizard. * * @param elevation * The elevation, which should be set, in dp as an {@link Integer} value. The elevation * must be at least 0 and at maximum 16 */ public final void setButtonBarElevation(final int elevation) { Condition.INSTANCE.ensureAtLeast(elevation, 0, "The elevation must be at least 0"); Condition.INSTANCE.ensureAtMaximum(elevation, ElevationUtil.MAX_ELEVATION, "The elevation must be at maximum " + ElevationUtil.MAX_ELEVATION); this.buttonBarElevation = elevation; adaptButtonBarElevation(); }
/** * Sets the view recycler, which allows to inflate the views, which are used to visualize tabs. * * @param viewRecycler * The view recycler, which should be set, as an instance of the class * AttachedViewRecycler. The view recycler may not be null */ public final void setViewRecycler( @NonNull final AttachedViewRecycler<AbstractItem, Integer> viewRecycler) { Condition.INSTANCE.ensureNotNull(viewRecycler, "The view recycler may not be null"); this.viewRecycler = viewRecycler; }
/** * Creates a new swipe animation. * * @param duration * The duration of the animation in milliseconds as a {@link Long} value or -1, if the * default duration should be used * @param interpolator * The interpolator, which should be used by the animation, as an instance of the type * {@link Interpolator} or null, if the default interpolator should be used * @param direction * The direction of the swipe animation as a value of the enum {@link SwipeDirection}. * The direction may not be null * @param relocateAnimationDuration * The duration of the animations, which are used to relocate other tabs, when a tab has * been added or removed, in milliseconds as a {@link Long} value or -1, if the default * duration should be used */ private SwipeAnimation(final long duration, @Nullable final Interpolator interpolator, @NonNull final SwipeDirection direction, final long relocateAnimationDuration) { super(duration, interpolator); Condition.INSTANCE.ensureNotNull(direction, "The direction may not be null"); Condition.INSTANCE.ensureAtLeast(relocateAnimationDuration, -1, "The relocate animation duration must be at least -1"); this.direction = direction; this.relocateAnimationDuration = relocateAnimationDuration; }
@Override public final int getTabSwitcherPadding(@NonNull final Axis axis, final int gravity) { Condition.INSTANCE.ensureNotNull(axis, "The axis may not be null"); Condition.INSTANCE .ensureTrue(gravity == Gravity.START || gravity == Gravity.END, "Invalid gravity"); if (getOrientationInvariantAxis(axis) == Axis.DRAGGING_AXIS) { return gravity == Gravity.START ? getTabSwitcher().getPaddingTop() : getTabSwitcher().getPaddingBottom(); } else { return gravity == Gravity.START ? getTabSwitcher().getPaddingLeft() : getTabSwitcher().getPaddingRight(); } }
@Override public final void setNumber(final int number) { Condition.INSTANCE.ensureAtMaximum(Integer.toString(number).length(), getNumberOfDigits(), "The number must have at maximum " + getNumberOfDigits() + " digits"); currentNumber = number; super.setNumber(number); }
@Override public final void onTabAdded(final int index, @NonNull final Tab tab, final int previousSelectedTabIndex, final int selectedTabIndex, final boolean selectionChanged, final boolean switcherVisibilityChanged, @NonNull final Animation animation) { getLogger().logInfo(getClass(), "Added tab at index " + index + " using a " + animation.getClass().getSimpleName()); if (animation instanceof PeekAnimation && getModel().getCount() > 1) { Condition.INSTANCE.ensureTrue(switcherVisibilityChanged, animation.getClass().getSimpleName() + " not supported when the tab switcher is shown"); PeekAnimation peekAnimation = (PeekAnimation) animation; AbstractItem item = TabItem.create(getModel(), 0, tab); inflateView(item, createPeekLayoutListener(item, peekAnimation)); } else if (animation instanceof RevealAnimation && switcherVisibilityChanged) { AbstractItem item = TabItem.create(getModel(), 0, tab); RevealAnimation revealAnimation = (RevealAnimation) animation; inflateView(item, createRevealLayoutListener(item, revealAnimation)); } else { addAllTabs(index, new Tab[]{tab}, animation); } adaptEmptyView( getModel().isSwitcherShown() ? getModel().getEmptyViewAnimationDuration() : 0); }