Skip to main content

Android-PageViewer

source code here

I've searched for a page Viewer to swipe the pages for the better view .. I found some of the snippets while searching for that ...

I used  the dotted Indication using  CirclePageIndicator in my package "com.rakesh.view"


The Java files in this package are

CirclePageIndicator.java



public class CirclePageIndicator extends View implements PageIndicator {
    private static final int INVALID_POINTER = -1;

    private float mRadius;
    private final Paint mPaintPageFill = new Paint(ANTI_ALIAS_FLAG);
    private final Paint mPaintStroke = new Paint(ANTI_ALIAS_FLAG);
    private final Paint mPaintFill = new Paint(ANTI_ALIAS_FLAG);
    private ViewPager mViewPager;
    private ViewPager.OnPageChangeListener mListener;
    private int mCurrentPage;
    private int mSnapPage;
    private float mPageOffset;
    private int mScrollState;
    private int mOrientation;
    private boolean mCentered;
    private boolean mSnap;

    private int mTouchSlop;
    private float mLastMotionX = -1;
    private int mActivePointerId = INVALID_POINTER;
    private boolean mIsDragging;


    public CirclePageIndicator(Context context) {
        this(context, null);
    }

    public CirclePageIndicator(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.vpiCirclePageIndicatorStyle);
    }

    public CirclePageIndicator(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if (isInEditMode()) return;

        //Load defaults from resources
        final Resources res = getResources();
        final int defaultPageColor = res.getColor(R.color.default_circle_indicator_page_color);
        final int defaultFillColor = res.getColor(R.color.default_circle_indicator_fill_color);
        final int defaultOrientation = res.getInteger(R.integer.default_circle_indicator_orientation);
        final int defaultStrokeColor = res.getColor(R.color.default_circle_indicator_stroke_color);
        final float defaultStrokeWidth = res.getDimension(R.dimen.default_circle_indicator_stroke_width);
        final float defaultRadius = res.getDimension(R.dimen.default_circle_indicator_radius);
        final boolean defaultCentered = res.getBoolean(R.bool.default_circle_indicator_centered);
        final boolean defaultSnap = res.getBoolean(R.bool.default_circle_indicator_snap);

        //Retrieve styles attributes
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CirclePageIndicator, defStyle, 0);

        mCentered = a.getBoolean(R.styleable.CirclePageIndicator_centered, defaultCentered);
        mOrientation = a.getInt(R.styleable.CirclePageIndicator_android_orientation, defaultOrientation);
        mPaintPageFill.setStyle(Style.FILL);
        mPaintPageFill.setColor(a.getColor(R.styleable.CirclePageIndicator_pageColor, defaultPageColor));
        mPaintStroke.setStyle(Style.STROKE);
        mPaintStroke.setColor(a.getColor(R.styleable.CirclePageIndicator_strokeColor, defaultStrokeColor));
        mPaintStroke.setStrokeWidth(a.getDimension(R.styleable.CirclePageIndicator_strokeWidth, defaultStrokeWidth));
        mPaintFill.setStyle(Style.FILL);
        mPaintFill.setColor(a.getColor(R.styleable.CirclePageIndicator_fillColor, defaultFillColor));
        mRadius = a.getDimension(R.styleable.CirclePageIndicator_radius, defaultRadius);
        mSnap = a.getBoolean(R.styleable.CirclePageIndicator_snap, defaultSnap);

        Drawable background = a.getDrawable(R.styleable.CirclePageIndicator_android_background);
        if (background != null) {
          setBackgroundDrawable(background);
        }

        a.recycle();

        final ViewConfiguration configuration = ViewConfiguration.get(context);
        mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
    }


    public void setCentered(boolean centered) {
        mCentered = centered;
        invalidate();
    }

    public boolean isCentered() {
        return mCentered;
    }

    public void setPageColor(int pageColor) {
        mPaintPageFill.setColor(pageColor);
        invalidate();
    }

    public int getPageColor() {
        return mPaintPageFill.getColor();
    }

    public void setFillColor(int fillColor) {
        mPaintFill.setColor(fillColor);
        invalidate();
    }

    public int getFillColor() {
        return mPaintFill.getColor();
    }

    public void setOrientation(int orientation) {
        switch (orientation) {
            case HORIZONTAL:
            case VERTICAL:
                mOrientation = orientation;
                requestLayout();
                break;

            default:
                throw new IllegalArgumentException("Orientation must be either HORIZONTAL or VERTICAL.");
        }
    }

    public int getOrientation() {
        return mOrientation;
    }

    public void setStrokeColor(int strokeColor) {
        mPaintStroke.setColor(strokeColor);
        invalidate();
    }

    public int getStrokeColor() {
        return mPaintStroke.getColor();
    }

    public void setStrokeWidth(float strokeWidth) {
        mPaintStroke.setStrokeWidth(strokeWidth);
        invalidate();
    }

    public float getStrokeWidth() {
        return mPaintStroke.getStrokeWidth();
    }

    public void setRadius(float radius) {
        mRadius = radius;
        invalidate();
    }

    public float getRadius() {
        return mRadius;
    }

    public void setSnap(boolean snap) {
        mSnap = snap;
        invalidate();
    }

    public boolean isSnap() {
        return mSnap;
    }

  
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (mViewPager == null) {
            return;
        }
        final int count = mViewPager.getAdapter().getCount();
        if (count == 0) {
            return;
        }

        if (mCurrentPage >= count) {
            setCurrentItem(count - 1);
            return;
        }

        int longSize;
        int longPaddingBefore;
        int longPaddingAfter;
        int shortPaddingBefore;
        if (mOrientation == HORIZONTAL) {
            longSize = getWidth();
            longPaddingBefore = getPaddingLeft();
            longPaddingAfter = getPaddingRight();
            shortPaddingBefore = getPaddingTop();
        } else {
            longSize = getHeight();
            longPaddingBefore = getPaddingTop();
            longPaddingAfter = getPaddingBottom();
            shortPaddingBefore = getPaddingLeft();
        }

        final float threeRadius = mRadius * 3;
        final float shortOffset = shortPaddingBefore + mRadius;
        float longOffset = longPaddingBefore + mRadius;
        if (mCentered) {
            longOffset += ((longSize - longPaddingBefore - longPaddingAfter) / 2.0f) - ((count * threeRadius) / 2.0f);
        }

        float dX;
        float dY;

        float pageFillRadius = mRadius;
        if (mPaintStroke.getStrokeWidth() > 0) {
            pageFillRadius -= mPaintStroke.getStrokeWidth() / 2.0f;
        }

        //Draw stroked circles
        for (int iLoop = 0; iLoop < count; iLoop++) {
            float drawLong = longOffset + (iLoop * threeRadius);
            if (mOrientation == HORIZONTAL) {
                dX = drawLong;
                dY = shortOffset;
            } else {
                dX = shortOffset;
                dY = drawLong;
            }
            // Only paint fill if not completely transparent
            if (mPaintPageFill.getAlpha() > 0) {
                canvas.drawCircle(dX, dY, pageFillRadius, mPaintPageFill);
            }

            // Only paint stroke if a stroke width was non-zero
            if (pageFillRadius != mRadius) {
                canvas.drawCircle(dX, dY, mRadius, mPaintStroke);
            }
        }

        //Draw the filled circle according to the current scroll
        float cx = (mSnap ? mSnapPage : mCurrentPage) * threeRadius;
        if (!mSnap) {
            cx += mPageOffset * threeRadius;
        }
        if (mOrientation == HORIZONTAL) {
            dX = longOffset + cx;
            dY = shortOffset;
        } else {
            dX = shortOffset;
            dY = longOffset + cx;
        }
        canvas.drawCircle(dX, dY, mRadius, mPaintFill);
    }

    public boolean onTouchEvent(android.view.MotionEvent ev) {
        if (super.onTouchEvent(ev)) {
            return true;
        }
        if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
            return false;
        }

        final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
                mLastMotionX = ev.getX();
                break;

            case MotionEvent.ACTION_MOVE: {
                final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
                final float x = MotionEventCompat.getX(ev, activePointerIndex);
                final float deltaX = x - mLastMotionX;

                if (!mIsDragging) {
                    if (Math.abs(deltaX) > mTouchSlop) {
                        mIsDragging = true;
                    }
                }

                if (mIsDragging) {
                    mLastMotionX = x;
                    if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
                        mViewPager.fakeDragBy(deltaX);
                    }
                }

                break;
            }

            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (!mIsDragging) {
                    final int count = mViewPager.getAdapter().getCount();
                    final int width = getWidth();
                    final float halfWidth = width / 2f;
                    final float sixthWidth = width / 6f;

                    if ((mCurrentPage > 0) && (ev.getX() < halfWidth - sixthWidth)) {
                        if (action != MotionEvent.ACTION_CANCEL) {
                            mViewPager.setCurrentItem(mCurrentPage - 1);
                        }
                        return true;
                    } else if ((mCurrentPage < count - 1) && (ev.getX() > halfWidth + sixthWidth)) {
                        if (action != MotionEvent.ACTION_CANCEL) {
                            mViewPager.setCurrentItem(mCurrentPage + 1);
                        }
                        return true;
                    }
                }

                mIsDragging = false;
                mActivePointerId = INVALID_POINTER;
                if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
                break;

            case MotionEventCompat.ACTION_POINTER_DOWN: {
                final int index = MotionEventCompat.getActionIndex(ev);
                mLastMotionX = MotionEventCompat.getX(ev, index);
                mActivePointerId = MotionEventCompat.getPointerId(ev, index);
                break;
            }

            case MotionEventCompat.ACTION_POINTER_UP:
                final int pointerIndex = MotionEventCompat.getActionIndex(ev);
                final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
                if (pointerId == mActivePointerId) {
                    final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                    mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
                }
                mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
                break;
        }

        return true;
    }

  
    public void setViewPager(ViewPager view) {
        if (mViewPager == view) {
            return;
        }
        if (mViewPager != null) {
            mViewPager.setOnPageChangeListener(null);
        }
        if (view.getAdapter() == null) {
            throw new IllegalStateException("ViewPager does not have adapter instance.");
        }
        mViewPager = view;
        mViewPager.setOnPageChangeListener(this);
        invalidate();
    }

  
    public void setViewPager(ViewPager view, int initialPosition) {
        setViewPager(view);
        setCurrentItem(initialPosition);
    }

  
    public void setCurrentItem(int item) {
        if (mViewPager == null) {
            throw new IllegalStateException("ViewPager has not been bound.");
        }
        mViewPager.setCurrentItem(item);
        mCurrentPage = item;
        invalidate();
    }

  
    public void notifyDataSetChanged() {
        invalidate();
    }

  
    public void onPageScrollStateChanged(int state) {
        mScrollState = state;

        if (mListener != null) {
            mListener.onPageScrollStateChanged(state);
        }
    }

  
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        mCurrentPage = position;
        mPageOffset = positionOffset;
        invalidate();

        if (mListener != null) {
            mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
        }
    }

  
    public void onPageSelected(int position) {
        if (mSnap || mScrollState == ViewPager.SCROLL_STATE_IDLE) {
            mCurrentPage = position;
            mSnapPage = position;
            invalidate();
        }

        if (mListener != null) {
            mListener.onPageSelected(position);
        }
    }

  
    public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
        mListener = listener;
    }

    /*
     * (non-Javadoc)
     *
     * @see android.view.View#onMeasure(int, int)
     */
  
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mOrientation == HORIZONTAL) {
            setMeasuredDimension(measureLong(widthMeasureSpec), measureShort(heightMeasureSpec));
        } else {
            setMeasuredDimension(measureShort(widthMeasureSpec), measureLong(heightMeasureSpec));
        }
    }

    /**
     * Determines the width of this view
     *
     * @param measureSpec
     *            A measureSpec packed into an int
     * @return The width of the view, honoring constraints from measureSpec
     */
    private int measureLong(int measureSpec) {
        int result;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if ((specMode == MeasureSpec.EXACTLY) || (mViewPager == null)) {
            //We were told how big to be
            result = specSize;
        } else {
            //Calculate the width according the views count
            final int count = mViewPager.getAdapter().getCount();
            result = (int)(getPaddingLeft() + getPaddingRight()
                    + (count * 2 * mRadius) + (count - 1) * mRadius + 1);
            //Respect AT_MOST value if that was what is called for by measureSpec
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    /**
     * Determines the height of this view
     *
     * @param measureSpec
     *            A measureSpec packed into an int
     * @return The height of the view, honoring constraints from measureSpec
     */
    private int measureShort(int measureSpec) {
        int result;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            //We were told how big to be
            result = specSize;
        } else {
            //Measure the height
            result = (int)(2 * mRadius + getPaddingTop() + getPaddingBottom() + 1);
            //Respect AT_MOST value if that was what is called for by measureSpec
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

  
    public void onRestoreInstanceState(Parcelable state) {
        SavedState savedState = (SavedState)state;
        super.onRestoreInstanceState(savedState.getSuperState());
        mCurrentPage = savedState.currentPage;
        mSnapPage = savedState.currentPage;
        requestLayout();
    }

  
    public Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        SavedState savedState = new SavedState(superState);
        savedState.currentPage = mCurrentPage;
        return savedState;
    }

    static class SavedState extends BaseSavedState {
        int currentPage;

        public SavedState(Parcelable superState) {
            super(superState);
        }

        private SavedState(Parcel in) {
            super(in);
            currentPage = in.readInt();
        }

      
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeInt(currentPage);
        }

        @SuppressWarnings("UnusedDeclaration")
        public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
          
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

          
            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }
}

 PageIndicator.java


package com.rakesh.view;

import android.support.v4.view.ViewPager;


public interface PageIndicator extends ViewPager.OnPageChangeListener {
    /**
     * Bind the indicator to a ViewPager.
     *
     * @param view
     */
    void setViewPager(ViewPager view);

    /**
     * Bind the indicator to a ViewPager.
     *
     * @param view
     * @param initialPosition
     */
    void setViewPager(ViewPager view, int initialPosition);

    /**
     * <p>Set the current page of both the ViewPager and indicator.</p>
     *
     * <p>This <strong>must</strong> be used if you need to set the page before
     * the views are drawn on screen (e.g., default start page).</p>
     *
     * @param item
     */
    void setCurrentItem(int item);

    /**
     * Set a page change listener which will receive forwarded events.
     *
     * @param listener
     */
    void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);

    /**
     * Notify the indicator that the fragment list has changed.
     */
    void notifyDataSetChanged();
}



I have another package called "com.example.pageviewer"


MainActivity.java



package com.example.viewpager;


import com.rakesh.view.CirclePageIndicator;

import android.os.Bundle;
import android.app.Activity;
import android.support.v4.view.ViewPager;
public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyPagerAdapter adapter = new MyPagerAdapter();
      
        ViewPager risk = (ViewPager) findViewById(R.id.viewpager);
        risk.setAdapter(adapter);
        risk.setCurrentItem(1);
       CirclePageIndicator cri=
               (CirclePageIndicator)findViewById( R.id.indicator);
    cri.setViewPager(risk);
   
    }
}



MyPagerAdapter.java

package com.example.viewpager;

import android.app.Activity;
import android.content.Context;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

public class MyPagerAdapter extends PagerAdapter {
    View view;
    public int getCount() {
        return 3;
    }

    public Object instantiateItem(View collection, int position) {

        LayoutInflater inflater = (LayoutInflater) collection.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          
        int resId = 0;
        switch (position) {
        case 0:
            resId = R.layout.risk;
            view = inflater.inflate(resId, null);

            ((ViewPager) collection).addView(view, 0);
            final TextView tv=(TextView)view.findViewById(R.id.textView1);
            tv.setOnClickListener(new OnClickListener() {
               
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    tv.setText("hello");
                }
            });
           
            break;
        case 1:
            resId = R.layout.risk1;
            view = inflater.inflate(resId, null);

            ((ViewPager) collection).addView(view, 0);
            break;
        case 2:
            resId = R.layout.risk2;
      
            view = inflater.inflate(resId, null);

            ((ViewPager) collection).addView(view, 0);
            break;
     
        }

    
        return view;
    }

    @Override
    public void destroyItem(View arg0, int arg1, Object arg2) {
        ((ViewPager) arg0).removeView((View) arg2);

    }


    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == ((View) arg1);

    }

    @Override
    public Parcelable saveState() {
        return null;
    }
}



under res folder Just create "color" folder and place the following files into it.

vpi__dark_theme.xml

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="@color/vpi__bright_foreground_disabled_holo_dark"/>
    <item android:state_window_focused="false" android:color="@color/vpi__bright_foreground_holo_dark"/>
    <item android:state_pressed="true" android:color="@color/vpi__bright_foreground_holo_dark"/>
    <item android:state_selected="true" android:color="@color/vpi__bright_foreground_holo_dark"/>
    <!--item android:state_activated="true" android:color="@color/vpi__bright_foreground_holo_dark"/-->
    <item android:color="@color/vpi__bright_foreground_holo_dark"/> <!-- not selected -->
</selector>




vpi__light_theme.xml

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="@color/vpi__bright_foreground_disabled_holo_light"/>
    <item android:state_window_focused="false" android:color="@color/vpi__bright_foreground_holo_light"/>
    <item android:state_pressed="true" android:color="@color/vpi__bright_foreground_holo_light"/>
    <item android:state_selected="true" android:color="@color/vpi__bright_foreground_holo_light"/>
    <!--item android:state_activated="true" android:color="@color/vpi__bright_foreground_holo_light"/-->
    <item android:color="@color/vpi__bright_foreground_holo_light"/> <!-- not selected -->
   
</selector>


Under the layout folder just place the below files...

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#000000" xmlns:app="http://schemas.android.com/apk/res/com.example.viewpager">
    <com.rakesh.view.CirclePageIndicator
       android:layout_marginTop="20dp"
        android:id="@+id/indicator"
       
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
       />
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1" />
</LinearLayout>


 risk.xml


    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:text="Risk" />

    </RelativeLayout>

risk1.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:text="Rakesh" />

    </RelativeLayout>
risk2.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
  <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:text="Rakesh L" />


</RelativeLayout>


Under Values folder place the following files..

strings.xml

<resources>
<string name="app_name">ViewPager</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_main">MainActivity</string>

</resources>
styles.xml
<resources>

    <style name="AppTheme" parent="android:Theme.Light" />

</resources>

vpi__attrs.xml

    <?xml version="1.0" encoding="utf-8"?>

<resources>
    <declare-styleable name="ViewPagerIndicator">
        <!-- Style of the circle indicator. -->
        <attr name="vpiCirclePageIndicatorStyle" format="reference"/>
        <!-- Style of the icon indicator's views. -->
        <attr name="vpiIconPageIndicatorStyle" format="reference"/>
        <!-- Style of the line indicator. -->
        <attr name="vpiLinePageIndicatorStyle" format="reference"/>
        <!-- Style of the title indicator. -->
        <attr name="vpiTitlePageIndicatorStyle" format="reference"/>
        <!-- Style of the tab indicator's tabs. -->
        <attr name="vpiTabPageIndicatorStyle" format="reference"/>
        <!-- Style of the underline indicator. -->
        <attr name="vpiUnderlinePageIndicatorStyle" format="reference"/>
    </declare-styleable>

    <attr name="centered" format="boolean" />
    <attr name="selectedColor" format="color" />
    <attr name="strokeWidth" format="dimension" />
    <attr name="unselectedColor" format="color" />

    <declare-styleable name="CirclePageIndicator">
        <!-- Whether or not the indicators should be centered. -->
        <attr name="centered" />
        <!-- Color of the filled circle that represents the current page. -->
        <attr name="fillColor" format="color" />
        <!-- Color of the filled circles that represents pages. -->
        <attr name="pageColor" format="color" />
        <!-- Orientation of the indicator. -->
        <attr name="android:orientation"/>
        <!-- Radius of the circles. This is also the spacing between circles. -->
        <attr name="radius" format="dimension" />
        <!-- Whether or not the selected indicator snaps to the circles. -->
        <attr name="snap" format="boolean" />
        <!-- Color of the open circles. -->
        <attr name="strokeColor" format="color" />
        <!-- Width of the stroke used to draw the circles. -->
        <attr name="strokeWidth" />
        <!-- View background -->
        <attr name="android:background"/>
    </declare-styleable>

    <declare-styleable name="LinePageIndicator">
        <!-- Whether or not the indicators should be centered. -->
        <attr name="centered" />
        <!-- Color of the unselected lines that represent the pages. -->
        <attr name="unselectedColor" />
        <!-- Color of the selected line that represents the current page. -->
        <attr name="selectedColor" />
        <!-- Width of each indicator line. -->
        <attr name="lineWidth" format="dimension" />
        <!-- Width of each indicator line's stroke. -->
        <attr name="strokeWidth" />
        <!-- Width of the gap between each indicator line. -->
        <attr name="gapWidth" format="dimension" />
        <!-- View background -->
        <attr name="android:background"/>
    </declare-styleable>

    <declare-styleable name="TitlePageIndicator">
        <!-- Screen edge padding. -->
        <attr name="clipPadding" format="dimension" />
        <!-- Color of the footer line and indicator. -->
        <attr name="footerColor" format="color" />
        <!-- Height of the footer line. -->
        <attr name="footerLineHeight" format="dimension" />
        <!-- Style of the indicator. Default is triangle. -->
        <attr name="footerIndicatorStyle">
            <enum name="none" value="0" />
            <enum name="triangle" value="1" />
            <enum name="underline" value="2" />
        </attr>
        <!-- Height of the indicator above the footer line. -->
        <attr name="footerIndicatorHeight" format="dimension" />
        <!-- Left and right padding of the underline indicator. -->
        <attr name="footerIndicatorUnderlinePadding" format="dimension" />
        <!-- Padding between the bottom of the title and the footer. -->
        <attr name="footerPadding" format="dimension" />
        <!-- Position of the line. -->
        <attr name="linePosition">
            <enum name="bottom" value="0"/>
            <enum name="top" value="1"/>
        </attr>
        <!-- Color of the selected title. -->
        <attr name="selectedColor" />
        <!-- Whether or not the selected item is displayed as bold. -->
        <attr name="selectedBold" format="boolean" />
        <!-- Color of regular titles. -->
        <attr name="android:textColor" />
        <!-- Size of title text. -->
        <attr name="android:textSize" />
        <!-- Padding between titles when bumping into each other. -->
        <attr name="titlePadding" format="dimension" />
        <!-- Padding between titles and the top of the View. -->
        <attr name="topPadding" format="dimension" />
        <!-- View background -->
        <attr name="android:background"/>
    </declare-styleable>

    <declare-styleable name="UnderlinePageIndicator">
        <!-- Whether or not the selected indicator fades. -->
        <attr name="fades" format="boolean" />
        <!-- Length of the delay to fade the indicator. -->
        <attr name="fadeDelay" format="integer" />
        <!-- Length of the indicator fade to transparent. -->
        <attr name="fadeLength" format="integer" />
        <!-- Color of the selected line that represents the current page. -->
        <attr name="selectedColor" />
        <!-- View background -->
        <attr name="android:background"/>
    </declare-styleable>
</resources>

vpi__colors.xml

<?xml version="1.0" encoding="utf-8"?>

<resources>
    <color name="vpi__background_holo_dark">#ff000000</color>
    <color name="vpi__background_holo_light">#fff3f3f3</color>
    <color name="vpi__bright_foreground_holo_dark">@color/vpi__background_holo_light</color>
    <color name="vpi__bright_foreground_holo_light">@color/vpi__background_holo_dark</color>
    <color name="vpi__bright_foreground_disabled_holo_dark">#ff4c4c4c</color>
    <color name="vpi__bright_foreground_disabled_holo_light">#ffb2b2b2</color>
    <color name="vpi__bright_foreground_inverse_holo_dark">@color/vpi__bright_foreground_holo_light</color>
    <color name="vpi__bright_foreground_inverse_holo_light">@color/vpi__bright_foreground_holo_dark</color>
</resources>

vpi__defaults.xml

   <?xml version="1.0" encoding="utf-8"?>

<resources>
    <bool name="default_circle_indicator_centered">true</bool>
    <color name="default_circle_indicator_fill_color">#FFFFFFFF</color>
    <color name="default_circle_indicator_page_color">#00000000</color>
    <integer name="default_circle_indicator_orientation">0</integer>
    <dimen name="default_circle_indicator_radius">3dp</dimen>
    <bool name="default_circle_indicator_snap">false</bool>
    <color name="default_circle_indicator_stroke_color">#FFDDDDDD</color>
    <dimen name="default_circle_indicator_stroke_width">1dp</dimen>

    <dimen name="default_line_indicator_line_width">12dp</dimen>
    <dimen name="default_line_indicator_gap_width">4dp</dimen>
    <dimen name="default_line_indicator_stroke_width">1dp</dimen>
    <color name="default_line_indicator_selected_color">#FF33B5E5</color>
    <color name="default_line_indicator_unselected_color">#FFBBBBBB</color>
    <bool name="default_line_indicator_centered">true</bool>

    <dimen name="default_title_indicator_clip_padding">4dp</dimen>
    <color name="default_title_indicator_footer_color">#FF33B5E5</color>
    <dimen name="default_title_indicator_footer_line_height">2dp</dimen>
    <integer name="default_title_indicator_footer_indicator_style">2</integer>
    <dimen name="default_title_indicator_footer_indicator_height">4dp</dimen>
    <dimen name="default_title_indicator_footer_indicator_underline_padding">20dp</dimen>
    <dimen name="default_title_indicator_footer_padding">7dp</dimen>
    <integer name="default_title_indicator_line_position">0</integer>
    <color name="default_title_indicator_selected_color">#FFFFFFFF</color>
    <bool name="default_title_indicator_selected_bold">true</bool>
    <color name="default_title_indicator_text_color">#BBFFFFFF</color>
    <dimen name="default_title_indicator_text_size">15dp</dimen>
    <dimen name="default_title_indicator_title_padding">5dp</dimen>
    <dimen name="default_title_indicator_top_padding">7dp</dimen>

    <bool name="default_underline_indicator_fades">true</bool>
    <integer name="default_underline_indicator_fade_delay">300</integer>
    <integer name="default_underline_indicator_fade_length">400</integer>
    <color name="default_underline_indicator_selected_color">#FF33B5E5</color>
</resources>

vpi__styles.xml

  <?xml version="1.0" encoding="utf-8"?>

<resources>
    <style name="Theme.PageIndicatorDefaults" parent="android:Theme">
        <item name="vpiIconPageIndicatorStyle">@style/Widget.IconPageIndicator</item>
        <item name="vpiTabPageIndicatorStyle">@style/Widget.TabPageIndicator</item>
    </style>

    <style name="Widget">
    </style>

    <style name="Widget.TabPageIndicator" parent="Widget">
        <item name="android:gravity">center</item>
        <item name="android:background">@drawable/ic_launcher</item>
        <item name="android:paddingLeft">22dip</item>
        <item name="android:paddingRight">22dip</item>
        <item name="android:paddingTop">12dp</item>
        <item name="android:paddingBottom">12dp</item>
        <item name="android:textAppearance">@style/TextAppearance.TabPageIndicator</item>
        <item name="android:textSize">12sp</item>
        <item name="android:maxLines">1</item>
    </style>

    <style name="TextAppearance.TabPageIndicator" parent="Widget">
        <item name="android:textStyle">bold</item>
        <item name="android:textColor">@color/vpi__dark_theme</item>
    </style>

    <style name="Widget.IconPageIndicator" parent="Widget">
        <item name="android:layout_marginLeft">6dp</item>
        <item name="android:layout_marginRight">6dp</item>
    </style>
</resources>

Finally, AndroidManifest.xml


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.viewpager"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
   

Like CirclePageIndicator we can also use TabPageIndicator,TitlePageIndicator,UnderlinePageIndicator.. 

If u need code snippets of all of them or if u have any errors in these snippets... just comment to this post :)


I've attached the source code here

Comments

  1. This is the perfect way of to do page indicator in any app integration...... thank u ...

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. Thanks . This is easy to integrate. I need code for IconPageIndicator. Can you do the needful.

    ReplyDelete

Post a Comment

Popular posts from this blog

Circular Seek Bar - Example

MyView.java package com.rakesh.androidcircularseekbar; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class MyView extends View {     /** The context */     private Context mContext;     /** The listener to listen for changes */     private OnSeekChangeListener mListener;     /** The color of the progress ring */     private Paint circleColor;     /** the color of the inside circle. Acts as background color */     private Paint innerColor;     /** The progress circle ring background */     private Paint circleRing;   ...

SSL pinning in Android - A brief discussion

HTTP protocol Communication between the client and a server typically non-encrypted or plain text while we use HTTP protocol.  Pitfall Any middle hacker can interrupt the connection between the client and server and manipulate the data as it involves no encryption. How to overcome this ? As the domain owner one can purchase a digital certificate from CA(Certificate Authority) who are considered as trusted.  A certificate will contain the Owner's name, public key , Issuer's(CA's) name,Issuer's(CA's) signature, domain details, expiry date etc . After the SSL/Leaf certificate is associated with a domain,the communication between client and server will be encrypted. Now the HTTP will become HTTPs. Note : Associating the SSL certificate means it enable the encryption between client and server but does not mean ,the domain owner will never misuse your personal information. How does SSL work ? Pitfall There is a problem here. Let's assume that there is a hacker comes i...

Android - Activity Life cycle

The android activity provides 7 call backs which will be invoked based on the states of the activity For better undersatnding,The Activity A and Activity B with the all the call backs overridden. ActivityA :  public class ActivityA extends Activity {     @Override    protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         Log.e("A-OnCreate", "Object Creation");     }     public void next(View v) {         Intent i = new Intent(this, Main2Activity.class);         startActivity(i);     }     @Override    protected void onStart() {         super.onStart();         Log.e("A-onStart", "View is visible but will not be able to interact");     } ...