package com.tiger.quicknews.wedget.viewimage.Indicators;
import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.support.v4.view.PagerAdapter;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.tiger.quicknews.R;
import com.tiger.quicknews.wedget.viewimage.Tricks.InfinitePagerAdapter;
import com.tiger.quicknews.wedget.viewimage.Tricks.ViewPagerEx;
import java.util.ArrayList;
/**
* Pager Indicator.
*/
public class PagerIndicator extends LinearLayout implements ViewPagerEx.OnPageChangeListener {
private final Context mContext;
/**
* bind this Indicator with
* {@link com.example.androidimageslider.wedget.viewimage.Tricks.daimajia.slider.library.Tricks.ViewPagerEx}
*/
private ViewPagerEx mPager;
/**
* Variable to remember the previous selected indicator.
*/
private ImageView mPreviousSelectedIndicator;
/**
* Previous selected indicator position.
*/
private int mPreviousSelectedPosition;
/**
* Custom selected indicator style resource id.
*/
private int mUserSetUnSelectedIndicatorResId;
/**
* Custom unselected indicator style resource id.
*/
private int mUserSetSelectedIndicatorResId;
private Drawable mSelectedDrawable;
private Drawable mUnselectedDrawable;
/**
* This value is from {@link com.tiger.quicknews.wedget.viewimage.Animations.daimajia.slider.library.SliderAdapter}
* getRealCount() represent the indicator count that we should draw.
*/
private int mItemCount = 0;
private Shape mIndicatorShape = Shape.Oval;
private IndicatorVisibility mVisibility = IndicatorVisibility.Visible;
private final int mDefaultSelectedColor;
private final int mDefaultUnSelectedColor;
private final float mDefaultSelectedWidth;
private final float mDefaultSelectedHeight;
private final float mDefaultUnSelectedWidth;
private final float mDefaultUnSelectedHeight;
public enum IndicatorVisibility {
Visible,
Invisible;
};
private final GradientDrawable mUnSelectedGradientDrawable;
private final GradientDrawable mSelectedGradientDrawable;
private final LayerDrawable mSelectedLayerDrawable;
private final LayerDrawable mUnSelectedLayerDrawable;
private float mPadding_left;
private float mPadding_right;
private float mPadding_top;
private float mPadding_bottom;
private final float mSelectedPadding_Left;
private final float mSelectedPadding_Right;
private final float mSelectedPadding_Top;
private final float mSelectedPadding_Bottom;
private final float mUnSelectedPadding_Left;
private final float mUnSelectedPadding_Right;
private final float mUnSelectedPadding_Top;
private final float mUnSelectedPadding_Bottom;
/**
* Put all the indicators into a ArrayList, so we can remove them easily.
*/
private final ArrayList<ImageView> mIndicators = new ArrayList<ImageView>();
public PagerIndicator(Context context) {
this(context, null);
}
public PagerIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
final TypedArray attributes = context.obtainStyledAttributes(attrs,
R.styleable.PagerIndicator, 0, 0);
int visibility = attributes.getInt(R.styleable.PagerIndicator_visibility,
IndicatorVisibility.Visible.ordinal());
for (IndicatorVisibility v : IndicatorVisibility.values()) {
if (v.ordinal() == visibility) {
mVisibility = v;
break;
}
}
int shape = attributes.getInt(R.styleable.PagerIndicator_shape, Shape.Oval.ordinal());
for (Shape s : Shape.values()) {
if (s.ordinal() == shape) {
mIndicatorShape = s;
break;
}
}
mUserSetSelectedIndicatorResId = attributes.getResourceId(
R.styleable.PagerIndicator_selected_drawable,
0);
mUserSetUnSelectedIndicatorResId = attributes.getResourceId(
R.styleable.PagerIndicator_unselected_drawable,
0);
mDefaultSelectedColor = attributes.getColor(R.styleable.PagerIndicator_selected_color,
Color.rgb(255, 255, 255));
mDefaultUnSelectedColor = attributes.getColor(R.styleable.PagerIndicator_unselected_color,
Color.argb(33, 255, 255, 255));
mDefaultSelectedWidth = attributes.getDimension(R.styleable.PagerIndicator_selected_width,
(int) pxFromDp(6));
mDefaultSelectedHeight = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_selected_height, (int) pxFromDp(6));
mDefaultUnSelectedWidth = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_unselected_width, (int) pxFromDp(6));
mDefaultUnSelectedHeight = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_unselected_height, (int) pxFromDp(6));
mSelectedGradientDrawable = new GradientDrawable();
mUnSelectedGradientDrawable = new GradientDrawable();
mPadding_left = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_padding_left,
(int) pxFromDp(3));
mPadding_right = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_padding_right,
(int) pxFromDp(3));
mPadding_top = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_padding_top,
(int) pxFromDp(0));
mPadding_bottom = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_padding_bottom, (int) pxFromDp(0));
mPadding_left = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_padding_left,
(int) pxFromDp(3));
mPadding_right = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_padding_right,
(int) pxFromDp(3));
mPadding_top = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_padding_top,
(int) pxFromDp(0));
mPadding_bottom = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_padding_bottom, (int) pxFromDp(0));
mSelectedPadding_Left = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_selected_padding_left, (int) pxFromDp(3));
mSelectedPadding_Right = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_selected_padding_right, (int) pxFromDp(3));
mSelectedPadding_Top = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_selected_padding_top, (int) pxFromDp(0));
mSelectedPadding_Bottom = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_selected_padding_bottom, (int) pxFromDp(0));
mUnSelectedPadding_Left = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_unselected_padding_left, (int) pxFromDp(3));
mUnSelectedPadding_Right = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_unselected_padding_right, (int) pxFromDp(3));
mUnSelectedPadding_Top = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_unselected_padding_top, (int) pxFromDp(0));
mUnSelectedPadding_Bottom = attributes.getDimensionPixelSize(
R.styleable.PagerIndicator_unselected_padding_bottom, (int) pxFromDp(0));
mSelectedLayerDrawable = new LayerDrawable(new Drawable[] {
mSelectedGradientDrawable
});
mUnSelectedLayerDrawable = new LayerDrawable(new Drawable[] {
mUnSelectedGradientDrawable
});
setIndicatorStyleResource(mUserSetSelectedIndicatorResId, mUserSetUnSelectedIndicatorResId);
setDefaultIndicatorShape(mIndicatorShape);
setDefaultSelectedIndicatorSize(mDefaultSelectedWidth, mDefaultSelectedHeight, Unit.Px);
setDefaultUnselectedIndicatorSize(mDefaultUnSelectedWidth, mDefaultUnSelectedHeight,
Unit.Px);
setDefaultIndicatorColor(mDefaultSelectedColor, mDefaultUnSelectedColor);
setIndicatorVisibility(mVisibility);
setDefaultPadding(mPadding_left, mPadding_top, mPadding_right, mPadding_bottom, Unit.Px);
setDefaultSelectedPadding(mSelectedPadding_Left, mSelectedPadding_Top,
mSelectedPadding_Right, mSelectedPadding_Bottom, Unit.Px);
setDefaultUnSelectedPadding(mUnSelectedPadding_Left, mUnSelectedPadding_Top,
mUnSelectedPadding_Right, mUnSelectedPadding_Bottom, Unit.Px);
attributes.recycle();
}
public enum Shape {
Oval, Rectangle
}
public void setDefaultPadding(float left, float top, float right, float bottom, Unit unit) {
if (mUserSetSelectedIndicatorResId == 0) {
if (unit == Unit.DP) {
mSelectedLayerDrawable.setLayerInset(0,
(int) pxFromDp(left), (int) pxFromDp(top),
(int) pxFromDp(right), (int) pxFromDp(bottom));
mUnSelectedLayerDrawable.setLayerInset(0,
(int) pxFromDp(left), (int) pxFromDp(top),
(int) pxFromDp(right), (int) pxFromDp(bottom));
} else {
mSelectedLayerDrawable.setLayerInset(0,
(int) left, (int) top,
(int) right, (int) bottom);
mUnSelectedLayerDrawable.setLayerInset(0,
(int) left, (int) top,
(int) right, (int) bottom);
}
}
}
public void setDefaultSelectedPadding(float left, float top, float right, float bottom,
Unit unit) {
if (mUserSetSelectedIndicatorResId == 0) {
if (unit == Unit.DP) {
mSelectedLayerDrawable.setLayerInset(0,
(int) pxFromDp(left), (int) pxFromDp(top),
(int) pxFromDp(right), (int) pxFromDp(bottom));
} else {
mSelectedLayerDrawable.setLayerInset(0,
(int) left, (int) top,
(int) right, (int) bottom);
}
}
}
public void setDefaultUnSelectedPadding(float left, float top, float right, float bottom,
Unit unit) {
if (mUserSetSelectedIndicatorResId == 0) {
if (unit == Unit.DP) {
mUnSelectedLayerDrawable.setLayerInset(0,
(int) pxFromDp(left), (int) pxFromDp(top),
(int) pxFromDp(right), (int) pxFromDp(bottom));
} else {
mUnSelectedLayerDrawable.setLayerInset(0,
(int) left, (int) top,
(int) right, (int) bottom);
}
}
}
/**
* if you are using the default indicator, this method will help you to set
* the shape of indicator, there are two kind of shapes you can set, oval
* and rect.
*
* @param shape
*/
public void setDefaultIndicatorShape(Shape shape) {
if (mUserSetSelectedIndicatorResId == 0) {
if (shape == Shape.Oval) {
mSelectedGradientDrawable.setShape(GradientDrawable.OVAL);
} else {
mSelectedGradientDrawable.setShape(GradientDrawable.RECTANGLE);
}
}
if (mUserSetUnSelectedIndicatorResId == 0) {
if (shape == Shape.Oval) {
mUnSelectedGradientDrawable.setShape(GradientDrawable.OVAL);
} else {
mUnSelectedGradientDrawable.setShape(GradientDrawable.RECTANGLE);
}
}
resetDrawable();
}
/**
* Set Indicator style.
*
* @param selected page selected drawable
* @param unselected page unselected drawable
*/
public void setIndicatorStyleResource(int selected, int unselected) {
mUserSetSelectedIndicatorResId = selected;
mUserSetUnSelectedIndicatorResId = unselected;
if (selected == 0) {
mSelectedDrawable = mSelectedLayerDrawable;
} else {
mSelectedDrawable = mContext.getResources().getDrawable(mUserSetSelectedIndicatorResId);
}
if (unselected == 0) {
mUnselectedDrawable = mUnSelectedLayerDrawable;
} else {
mUnselectedDrawable = mContext.getResources().getDrawable(
mUserSetUnSelectedIndicatorResId);
}
resetDrawable();
}
/**
* if you are using the default indicator , this method will help you to set
* the selected status and the unselected status color.
*
* @param selectedColor
* @param unselectedColor
*/
public void setDefaultIndicatorColor(int selectedColor, int unselectedColor) {
if (mUserSetSelectedIndicatorResId == 0) {
mSelectedGradientDrawable.setColor(selectedColor);
}
if (mUserSetUnSelectedIndicatorResId == 0) {
mUnSelectedGradientDrawable.setColor(unselectedColor);
}
resetDrawable();
}
public enum Unit {
DP, Px
}
public void setDefaultSelectedIndicatorSize(float width, float height, Unit unit) {
if (mUserSetSelectedIndicatorResId == 0) {
float w = width;
float h = height;
if (unit == Unit.DP) {
w = pxFromDp(width);
h = pxFromDp(height);
}
mSelectedGradientDrawable.setSize((int) w, (int) h);
resetDrawable();
}
}
public void setDefaultUnselectedIndicatorSize(float width, float height, Unit unit) {
if (mUserSetUnSelectedIndicatorResId == 0) {
float w = width;
float h = height;
if (unit == Unit.DP) {
w = pxFromDp(width);
h = pxFromDp(height);
}
mUnSelectedGradientDrawable.setSize((int) w, (int) h);
resetDrawable();
}
}
public void setDefaultIndicatorSize(float width, float height, Unit unit) {
setDefaultSelectedIndicatorSize(width, height, unit);
setDefaultUnselectedIndicatorSize(width, height, unit);
}
private float dpFromPx(float px)
{
return px / this.getContext().getResources().getDisplayMetrics().density;
}
private float pxFromDp(float dp)
{
return dp * this.getContext().getResources().getDisplayMetrics().density;
}
/**
* set the visibility of indicator.
*
* @param visibility
*/
public void setIndicatorVisibility(IndicatorVisibility visibility) {
if (visibility == IndicatorVisibility.Visible) {
setVisibility(View.VISIBLE);
} else {
setVisibility(View.INVISIBLE);
}
resetDrawable();
}
/**
* clear self means unregister the dataset observer and remove all the child
* views(indicators).
*/
public void destroySelf() {
if (mPager == null || mPager.getAdapter() == null) {
return;
}
InfinitePagerAdapter wrapper = (InfinitePagerAdapter) mPager.getAdapter();
PagerAdapter adapter = wrapper.getRealAdapter();
if (adapter != null) {
adapter.unregisterDataSetObserver(dataChangeObserver);
}
removeAllViews();
ShapeDrawable shapeDrawable;
}
/**
* bind indicator with viewpagerEx.
*
* @param pager
*/
public void setViewPager(ViewPagerEx pager) {
if (pager.getAdapter() == null) {
throw new IllegalStateException("Viewpager does not have adapter instance");
}
mPager = pager;
mPager.setOnPageChangeListener(this);
((InfinitePagerAdapter) mPager.getAdapter()).getRealAdapter().registerDataSetObserver(
dataChangeObserver);
}
private void resetDrawable() {
for (View i : mIndicators) {
if (mPreviousSelectedIndicator != null && mPreviousSelectedIndicator.equals(i)) {
((ImageView) i).setImageDrawable(mSelectedDrawable);
}
else {
((ImageView) i).setImageDrawable(mUnselectedDrawable);
}
}
}
/**
* redraw the indicators.
*/
public void redraw() {
mItemCount = getShouldDrawCount();
mPreviousSelectedIndicator = null;
for (View i : mIndicators) {
removeView(i);
}
for (int i = 0; i < mItemCount; i++) {
ImageView indicator = new ImageView(mContext);
indicator.setImageDrawable(mUnselectedDrawable);
addView(indicator);
mIndicators.add(indicator);
}
setItemAsSelected(mPreviousSelectedPosition);
}
/**
* since we used a adapter wrapper, so we can't getCount directly from
* wrapper.
*
* @return
*/
private int getShouldDrawCount() {
if (mPager.getAdapter() instanceof InfinitePagerAdapter) {
return ((InfinitePagerAdapter) mPager.getAdapter()).getRealCount();
} else {
return mPager.getAdapter().getCount();
}
}
private final DataSetObserver dataChangeObserver = new DataSetObserver() {
@Override
public void onChanged() {
PagerAdapter adapter = mPager.getAdapter();
int count = 0;
if (adapter instanceof InfinitePagerAdapter) {
count = ((InfinitePagerAdapter) adapter).getRealCount();
} else {
count = adapter.getCount();
}
if (count > mItemCount) {
for (int i = 0; i < count - mItemCount; i++) {
ImageView indicator = new ImageView(mContext);
indicator.setImageDrawable(mUnselectedDrawable);
addView(indicator);
mIndicators.add(indicator);
}
} else if (count < mItemCount) {
for (int i = 0; i < mItemCount - count; i++) {
removeView(mIndicators.get(0));
mIndicators.remove(0);
}
}
mItemCount = count;
mPager.setCurrentItem(mItemCount * 20 + mPager.getCurrentItem());
}
@Override
public void onInvalidated() {
super.onInvalidated();
redraw();
}
};
private void setItemAsSelected(int position) {
if (mPreviousSelectedIndicator != null) {
mPreviousSelectedIndicator.setImageDrawable(mUnselectedDrawable);
}
ImageView currentSelected = (ImageView) getChildAt(position + 1);
if (currentSelected != null) {
currentSelected.setImageDrawable(mSelectedDrawable);
mPreviousSelectedIndicator = currentSelected;
}
mPreviousSelectedPosition = position;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (mItemCount == 0) {
return;
}
int n = position % mItemCount;
setItemAsSelected(n - 1);
}
public IndicatorVisibility getIndicatorVisibility() {
return mVisibility;
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
public int getSelectedIndicatorResId() {
return mUserSetSelectedIndicatorResId;
}
public int getUnSelectedIndicatorResId() {
return mUserSetUnSelectedIndicatorResId;
}
}