1 package com.viewpagerindicator;
3 import android.content.Context;
4 import android.content.res.TypedArray;
5 import android.graphics.Canvas;
6 import android.graphics.drawable.Drawable;
7 import android.view.View;
8 import android.widget.LinearLayout;
11 * A simple extension of a regular linear layout that supports the divider API
12 * of Android 4.0+. The dividers are added adjacent to the children by changing
13 * their layout params. If you need to rely on the margins which fall in the
14 * same orientation as the layout you should wrap the child in a simple
15 * {@link android.widget.FrameLayout} so it can receive the margin.
17 class IcsLinearLayout extends LinearLayout {
18 private static final int[] LL = new int[] {
19 /* 0 */ android.R.attr.divider,
20 /* 1 */ android.R.attr.showDividers,
21 /* 2 */ android.R.attr.dividerPadding,
23 private static final int LL_DIVIDER = 0;
24 private static final int LL_SHOW_DIVIDER = 1;
25 private static final int LL_DIVIDER_PADDING = 2;
27 private Drawable mDivider;
28 private int mDividerWidth;
29 private int mDividerHeight;
30 private int mShowDividers;
31 private int mDividerPadding;
34 public IcsLinearLayout(Context context, int themeAttr) {
37 TypedArray a = context.obtainStyledAttributes(null, LL, themeAttr, 0);
38 setDividerDrawable(a.getDrawable(IcsLinearLayout.LL_DIVIDER));
39 mDividerPadding = a.getDimensionPixelSize(LL_DIVIDER_PADDING, 0);
40 mShowDividers = a.getInteger(LL_SHOW_DIVIDER, SHOW_DIVIDER_NONE);
44 public void setDividerDrawable(Drawable divider) {
45 if (divider == mDivider) {
49 if (divider != null) {
50 mDividerWidth = divider.getIntrinsicWidth();
51 mDividerHeight = divider.getIntrinsicHeight();
56 setWillNotDraw(divider == null);
61 protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
62 final int index = indexOfChild(child);
63 final int orientation = getOrientation();
64 final LayoutParams params = (LayoutParams) child.getLayoutParams();
65 if (hasDividerBeforeChildAt(index)) {
66 if (orientation == VERTICAL) {
67 //Account for the divider by pushing everything up
68 params.topMargin = mDividerHeight;
70 //Account for the divider by pushing everything left
71 params.leftMargin = mDividerWidth;
75 final int count = getChildCount();
76 if (index == count - 1) {
77 if (hasDividerBeforeChildAt(count)) {
78 if (orientation == VERTICAL) {
79 params.bottomMargin = mDividerHeight;
81 params.rightMargin = mDividerWidth;
85 super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed);
89 protected void onDraw(Canvas canvas) {
90 if (mDivider != null) {
91 if (getOrientation() == VERTICAL) {
92 drawDividersVertical(canvas);
94 drawDividersHorizontal(canvas);
100 private void drawDividersVertical(Canvas canvas) {
101 final int count = getChildCount();
102 for (int i = 0; i < count; i++) {
103 final View child = getChildAt(i);
105 if (child != null && child.getVisibility() != GONE) {
106 if (hasDividerBeforeChildAt(i)) {
107 final android.widget.LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) child.getLayoutParams();
108 final int top = child.getTop() - lp.topMargin/* - mDividerHeight*/;
109 drawHorizontalDivider(canvas, top);
114 if (hasDividerBeforeChildAt(count)) {
115 final View child = getChildAt(count - 1);
118 bottom = getHeight() - getPaddingBottom() - mDividerHeight;
120 //final LayoutParams lp = (LayoutParams) child.getLayoutParams();
121 bottom = child.getBottom()/* + lp.bottomMargin*/;
123 drawHorizontalDivider(canvas, bottom);
127 private void drawDividersHorizontal(Canvas canvas) {
128 final int count = getChildCount();
129 for (int i = 0; i < count; i++) {
130 final View child = getChildAt(i);
132 if (child != null && child.getVisibility() != GONE) {
133 if (hasDividerBeforeChildAt(i)) {
134 final android.widget.LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) child.getLayoutParams();
135 final int left = child.getLeft() - lp.leftMargin/* - mDividerWidth*/;
136 drawVerticalDivider(canvas, left);
141 if (hasDividerBeforeChildAt(count)) {
142 final View child = getChildAt(count - 1);
145 right = getWidth() - getPaddingRight() - mDividerWidth;
147 //final LayoutParams lp = (LayoutParams) child.getLayoutParams();
148 right = child.getRight()/* + lp.rightMargin*/;
150 drawVerticalDivider(canvas, right);
154 private void drawHorizontalDivider(Canvas canvas, int top) {
155 mDivider.setBounds(getPaddingLeft() + mDividerPadding, top,
156 getWidth() - getPaddingRight() - mDividerPadding, top + mDividerHeight);
157 mDivider.draw(canvas);
160 private void drawVerticalDivider(Canvas canvas, int left) {
161 mDivider.setBounds(left, getPaddingTop() + mDividerPadding,
162 left + mDividerWidth, getHeight() - getPaddingBottom() - mDividerPadding);
163 mDivider.draw(canvas);
166 protected boolean hasDividerBeforeChildAt(int childIndex) {
167 if (childIndex == 0 || childIndex == getChildCount()) {
170 if ((mShowDividers & SHOW_DIVIDER_MIDDLE) != 0) {
171 boolean hasVisibleViewBefore = false;
172 for (int i = childIndex - 1; i >= 0; i--) {
173 if (getChildAt(i).getVisibility() != GONE) {
174 hasVisibleViewBefore = true;
178 return hasVisibleViewBefore;