All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.devnied.emvnfccard.view.SlidingTabStrip Maven / Gradle / Ivy

There is a newer version: 2.1.1
Show newest version
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.github.devnied.emvnfccard.view;

import android.R;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.widget.LinearLayout;

class SlidingTabStrip extends LinearLayout {

	private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 0;
	private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
	private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8;
	private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;

	private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1;
	private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20;
	private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f;

	private final int mBottomBorderThickness;
	private final Paint mBottomBorderPaint;

	private final int mSelectedIndicatorThickness;
	private final Paint mSelectedIndicatorPaint;

	private final int mDefaultBottomBorderColor;

	private final Paint mDividerPaint;
	private final float mDividerHeight;

	private int mSelectedPosition;
	private float mSelectionOffset;

	private SlidingTabLayout.TabColorizer mCustomTabColorizer;
	private final SimpleTabColorizer mDefaultTabColorizer;

	SlidingTabStrip(final Context context) {
		this(context, null);
	}

	SlidingTabStrip(final Context context, final AttributeSet attrs) {
		super(context, attrs);
		setWillNotDraw(false);

		final float density = getResources().getDisplayMetrics().density;

		TypedValue outValue = new TypedValue();
		context.getTheme().resolveAttribute(R.attr.colorForeground, outValue, true);
		final int themeForegroundColor = outValue.data;

		mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor, DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);

		mDefaultTabColorizer = new SimpleTabColorizer();
		mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
		mDefaultTabColorizer.setDividerColors(setColorAlpha(themeForegroundColor, DEFAULT_DIVIDER_COLOR_ALPHA));

		mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
		mBottomBorderPaint = new Paint();
		mBottomBorderPaint.setColor(mDefaultBottomBorderColor);

		mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
		mSelectedIndicatorPaint = new Paint();

		mDividerHeight = DEFAULT_DIVIDER_HEIGHT;
		mDividerPaint = new Paint();
		mDividerPaint.setStrokeWidth((int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density));
	}

	void setCustomTabColorizer(final SlidingTabLayout.TabColorizer customTabColorizer) {
		mCustomTabColorizer = customTabColorizer;
		invalidate();
	}

	void setSelectedIndicatorColors(final int... colors) {
		// Make sure that the custom colorizer is removed
		mCustomTabColorizer = null;
		mDefaultTabColorizer.setIndicatorColors(colors);
		invalidate();
	}

	void setDividerColors(final int... colors) {
		// Make sure that the custom colorizer is removed
		mCustomTabColorizer = null;
		mDefaultTabColorizer.setDividerColors(colors);
		invalidate();
	}

	void onViewPagerPageChanged(final int position, final float positionOffset) {
		mSelectedPosition = position;
		mSelectionOffset = positionOffset;
		invalidate();
	}

	@Override
	protected void onDraw(final Canvas canvas) {
		final int height = getHeight();
		final int childCount = getChildCount();
		final int dividerHeightPx = (int) (Math.min(Math.max(0f, mDividerHeight), 1f) * height);
		final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null ? mCustomTabColorizer
				: mDefaultTabColorizer;

		// Thick colored underline below the current selection
		if (childCount > 0) {
			View selectedTitle = getChildAt(mSelectedPosition);
			int left = selectedTitle.getLeft();
			int right = selectedTitle.getRight();
			int color = tabColorizer.getIndicatorColor(mSelectedPosition);

			if (mSelectionOffset > 0f && mSelectedPosition < getChildCount() - 1) {
				int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
				if (color != nextColor) {
					color = blendColors(nextColor, color, mSelectionOffset);
				}

				// Draw the selection partway between the tabs
				View nextTitle = getChildAt(mSelectedPosition + 1);
				left = (int) (mSelectionOffset * nextTitle.getLeft() + (1.0f - mSelectionOffset) * left);
				right = (int) (mSelectionOffset * nextTitle.getRight() + (1.0f - mSelectionOffset) * right);
			}

			mSelectedIndicatorPaint.setColor(color);

			canvas.drawRect(left, height - mSelectedIndicatorThickness, right, height, mSelectedIndicatorPaint);
		}

		// Thin underline along the entire bottom edge
		canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);

		// Vertical separators between the titles
		int separatorTop = (height - dividerHeightPx) / 2;
		for (int i = 0; i < childCount - 1; i++) {
			View child = getChildAt(i);
			mDividerPaint.setColor(tabColorizer.getDividerColor(i));
			canvas.drawLine(child.getRight(), separatorTop, child.getRight(), separatorTop + dividerHeightPx, mDividerPaint);
		}
	}

	/**
	 * Set the alpha value of the {@code color} to be the given {@code alpha} value.
	 */
	private static int setColorAlpha(final int color, final byte alpha) {
		return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
	}

	/**
	 * Blend {@code color1} and {@code color2} using the given ratio.
	 * 
	 * @param ratio
	 *            of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend, 0.0 will return {@code color2}.
	 */
	private static int blendColors(final int color1, final int color2, final float ratio) {
		final float inverseRation = 1f - ratio;
		float r = Color.red(color1) * ratio + Color.red(color2) * inverseRation;
		float g = Color.green(color1) * ratio + Color.green(color2) * inverseRation;
		float b = Color.blue(color1) * ratio + Color.blue(color2) * inverseRation;
		return Color.rgb((int) r, (int) g, (int) b);
	}

	private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
		private int[] mIndicatorColors;
		private int[] mDividerColors;

		@Override
		public final int getIndicatorColor(final int position) {
			return mIndicatorColors[position % mIndicatorColors.length];
		}

		@Override
		public final int getDividerColor(final int position) {
			return mDividerColors[position % mDividerColors.length];
		}

		void setIndicatorColors(final int... colors) {
			mIndicatorColors = colors;
		}

		void setDividerColors(final int... colors) {
			mDividerColors = colors;
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy