content: /*
   * 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.example.android.common.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 = 2;
      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(Context context) {
          this(context, null);
      }
  
      SlidingTabStrip(Context context, 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(SlidingTabLayout.TabColorizer customTabColorizer) {
          mCustomTabColorizer = customTabColorizer;
          invalidate();
      }
  
      void setSelectedIndicatorColors(int... colors) {
          // Make sure that the custom colorizer is removed
          mCustomTabColorizer = null;
          mDefaultTabColorizer.setIndicatorColors(colors);
          invalidate();
      }
  
      void setDividerColors(int... colors) {
          // Make sure that the custom colorizer is removed
          mCustomTabColorizer = null;
          mDefaultTabColorizer.setDividerColors(colors);
          invalidate();
      }
  
      void onViewPagerPageChanged(int position, float positionOffset) {
          mSelectedPosition = position;
          mSelectionOffset = positionOffset;
          invalidate();
      }
  
      @Override
      protected void onDraw(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(int color, 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(int color1, int color2, 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(int position) {
              return mIndicatorColors[position % mIndicatorColors.length];
          }
  
          @Override
          public final int getDividerColor(int position) {
              return mDividerColors[position % mDividerColors.length];
          }
  
          void setIndicatorColors(int... colors) {
              mIndicatorColors = colors;
          }
  
          void setDividerColors(int... colors) {
              mDividerColors = colors;
          }
      }
  }