content: package com.actionbarsherlock.internal.widget;
  
  import android.content.Context;
  import android.content.res.TypedArray;
  import android.graphics.Canvas;
  import android.graphics.drawable.ColorDrawable;
  import android.graphics.drawable.Drawable;
  import android.os.Build;
  import android.util.AttributeSet;
  import android.view.View;
  
  import com.actionbarsherlock.internal.nineoldandroids.widget.NineLinearLayout;
  
  /**
   * A simple extension of a regular linear layout that supports the divider API
   * of Android 4.0+. The dividers are added adjacent to the children by changing
   * their layout params. If you need to rely on the margins which fall in the
   * same orientation as the layout you should wrap the child in a simple
   * {@link android.widget.FrameLayout} so it can receive the margin.
   */
  public class IcsLinearLayout extends NineLinearLayout {
      private static final int[] R_styleable_LinearLayout = new int[] {
          /* 0 */ android.R.attr.divider,
          /* 2 */ android.R.attr.showDividers,
          /* 3 */ android.R.attr.dividerPadding,
      };
      private static final int LinearLayout_divider = 0;
      private static final int LinearLayout_showDividers = 1;
      private static final int LinearLayout_dividerPadding = 2;
  
      /**
       * Don't show any dividers.
       */
      public static final int SHOW_DIVIDER_NONE = 0;
      /**
       * Show a divider at the beginning of the group.
       */
      public static final int SHOW_DIVIDER_BEGINNING = 1;
      /**
       * Show dividers between each item in the group.
       */
      public static final int SHOW_DIVIDER_MIDDLE = 2;
      /**
       * Show a divider at the end of the group.
       */
      public static final int SHOW_DIVIDER_END = 4;
  
  
      private Drawable mDivider;
      private int mDividerWidth;
      private int mDividerHeight;
      private int mShowDividers;
      private int mDividerPadding;
  
      public IcsLinearLayout(Context context, AttributeSet attrs) {
          super(context, attrs);
  
          TypedArray a = context.obtainStyledAttributes(attrs, /*com.android.internal.R.styleable.*/R_styleable_LinearLayout);
  
          setDividerDrawable(a.getDrawable(/*com.android.internal.R.styleable.*/LinearLayout_divider));
          mShowDividers = a.getInt(/*com.android.internal.R.styleable.*/LinearLayout_showDividers, SHOW_DIVIDER_NONE);
          mDividerPadding = a.getDimensionPixelSize(/*com.android.internal.R.styleable.*/LinearLayout_dividerPadding, 0);
  
          a.recycle();
      }
  
      /**
       * Set how dividers should be shown between items in this layout
       *
       * @param showDividers One or more of {@link #SHOW_DIVIDER_BEGINNING},
       *                     {@link #SHOW_DIVIDER_MIDDLE}, or {@link #SHOW_DIVIDER_END},
       *                     or {@link #SHOW_DIVIDER_NONE} to show no dividers.
       */
      public void setShowDividers(int showDividers) {
          if (showDividers != mShowDividers) {
              requestLayout();
              invalidate(); //XXX This is required if you are toggling a divider off
          }
          mShowDividers = showDividers;
      }
  
      /**
       * @return A flag set indicating how dividers should be shown around items.
       * @see #setShowDividers(int)
       */
      public int getShowDividers() {
          return mShowDividers;
      }
  
      /**
       * Set a drawable to be used as a divider between items.
       * @param divider Drawable that will divide each item.
       * @see #setShowDividers(int)
       */
      public void setDividerDrawable(Drawable divider) {
          if (divider == mDivider) {
              return;
          }
  
          //Fix for issue #379
          if (divider instanceof ColorDrawable && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
              divider = new IcsColorDrawable((ColorDrawable) divider);
          }
  
          mDivider = divider;
          if (divider != null) {
              mDividerWidth = divider.getIntrinsicWidth();
              mDividerHeight = divider.getIntrinsicHeight();
          } else {
              mDividerWidth = 0;
              mDividerHeight = 0;
          }
          setWillNotDraw(divider == null);
          requestLayout();
      }
  
      /**
       * Set padding displayed on both ends of dividers.
       *
       * @param padding Padding value in pixels that will be applied to each end
       *
       * @see #setShowDividers(int)
       * @see #setDividerDrawable(Drawable)
       * @see #getDividerPadding()
       */
      public void setDividerPadding(int padding) {
          mDividerPadding = padding;
      }
  
      /**
       * Get the padding size used to inset dividers in pixels
       *
       * @see #setShowDividers(int)
       * @see #setDividerDrawable(Drawable)
       * @see #setDividerPadding(int)
       */
      public int getDividerPadding() {
          return mDividerPadding;
      }
  
      /**
       * Get the width of the current divider drawable.
       *
       * @hide Used internally by framework.
       */
      public int getDividerWidth() {
          return mDividerWidth;
      }
  
      @Override
      protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
          final int index = indexOfChild(child);
          final int orientation = getOrientation();
          final LayoutParams params = (LayoutParams) child.getLayoutParams();
          if (hasDividerBeforeChildAt(index)) {
              if (orientation == VERTICAL) {
                  //Account for the divider by pushing everything up
                  params.topMargin = mDividerHeight;
              } else {
                  //Account for the divider by pushing everything left
                  params.leftMargin = mDividerWidth;
              }
          }
  
          final int count = getChildCount();
          if (index == count - 1) {
              if (hasDividerBeforeChildAt(count)) {
                  if (orientation == VERTICAL) {
                      params.bottomMargin = mDividerHeight;
                  } else {
                      params.rightMargin = mDividerWidth;
                  }
              }
          }
          super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed);
      }
  
      @Override
      protected void onDraw(Canvas canvas) {
          if (mDivider != null) {
              if (getOrientation() == VERTICAL) {
                  drawDividersVertical(canvas);
              } else {
                  drawDividersHorizontal(canvas);
              }
          }
          super.onDraw(canvas);
      }
  
      void drawDividersVertical(Canvas canvas) {
          final int count = getChildCount();
          for (int i = 0; i < count; i++) {
              final View child = getChildAt(i);
  
              if (child != null && child.getVisibility() != GONE) {
                  if (hasDividerBeforeChildAt(i)) {
                      final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                      final int top = child.getTop() - lp.topMargin/* - mDividerHeight*/;
                      drawHorizontalDivider(canvas, top);
                  }
              }
          }
  
          if (hasDividerBeforeChildAt(count)) {
              final View child = getChildAt(count - 1);
              int bottom = 0;
              if (child == null) {
                  bottom = getHeight() - getPaddingBottom() - mDividerHeight;
              } else {
                  //final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                  bottom = child.getBottom()/* + lp.bottomMargin*/;
              }
              drawHorizontalDivider(canvas, bottom);
          }
      }
  
      void drawDividersHorizontal(Canvas canvas) {
          final int count = getChildCount();
          for (int i = 0; i < count; i++) {
              final View child = getChildAt(i);
  
              if (child != null && child.getVisibility() != GONE) {
                  if (hasDividerBeforeChildAt(i)) {
                      final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                      final int left = child.getLeft() - lp.leftMargin/* - mDividerWidth*/;
                      drawVerticalDivider(canvas, left);
                  }
              }
          }
  
          if (hasDividerBeforeChildAt(count)) {
              final View child = getChildAt(count - 1);
              int right = 0;
              if (child == null) {
                  right = getWidth() - getPaddingRight() - mDividerWidth;
              } else {
                  //final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                  right = child.getRight()/* + lp.rightMargin*/;
              }
              drawVerticalDivider(canvas, right);
          }
      }
  
      void drawHorizontalDivider(Canvas canvas, int top) {
          mDivider.setBounds(getPaddingLeft() + mDividerPadding, top,
                  getWidth() - getPaddingRight() - mDividerPadding, top + mDividerHeight);
          mDivider.draw(canvas);
      }
  
      void drawVerticalDivider(Canvas canvas, int left) {
          mDivider.setBounds(left, getPaddingTop() + mDividerPadding,
                  left + mDividerWidth, getHeight() - getPaddingBottom() - mDividerPadding);
          mDivider.draw(canvas);
      }
  
      /**
       * Determines where to position dividers between children.
       *
       * @param childIndex Index of child to check for preceding divider
       * @return true if there should be a divider before the child at childIndex
       * @hide Pending API consideration. Currently only used internally by the system.
       */
      protected boolean hasDividerBeforeChildAt(int childIndex) {
          if (childIndex == 0) {
              return (mShowDividers & SHOW_DIVIDER_BEGINNING) != 0;
          } else if (childIndex == getChildCount()) {
              return (mShowDividers & SHOW_DIVIDER_END) != 0;
          } else if ((mShowDividers & SHOW_DIVIDER_MIDDLE) != 0) {
              boolean hasVisibleViewBefore = false;
              for (int i = childIndex - 1; i >= 0; i--) {
                  if (getChildAt(i).getVisibility() != GONE) {
                      hasVisibleViewBefore = true;
                      break;
                  }
              }
              return hasVisibleViewBefore;
          }
          return false;
      }
  }
  