Android Fragment Pager and Custom Page Indicator( ViewPagerIndicator created by Jake Wharton)

好久不见. 提交于 2019-12-29 08:45:09

问题


I am using ViewPageIndicator for developing a pager view with its indicator

MyCode

Activity

public class Pager extends Activity{

    private MyPagerAdapter mAdapter;
    private ViewPager mPager;
    private CirclePageIndicator mIndicator;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_pager);

    mAdapter=new MyPagerAdapter(getApplicationContext());

    mPager = (ViewPager)findViewById(R.id.pager);
    mPager.setAdapter(mAdapter);

    mIndicator = (CirclePageIndicator)findViewById(R.id.indicator);
    mIndicator.setViewPager(mPager);
}

MyPagerAdapter .java

public class MyPagerAdapter extends PagerAdapter{

 protected static final String[] CONTENT = new String[] { "This", "Is", "A", "Test", "Demo","Sample","Example" ,
        "Application","To","Study","And","Implement","Page-Viewer","And","Page-Indicator","For","News"};

        private Context ctx;
        private int mCount = CONTENT.length;

        public MyPagerAdapter(Context ctx){
            this.ctx = ctx;
        }

        @Override
        public int getCount() {
            return mCount;
        }


        @Override
        public Object instantiateItem(View collection, int position) {
            TextView view = new TextView(ctx);
            view.setGravity(Gravity.CENTER);
            view.setTextSize(20 );
            view.setPadding(20, 20, 20, 20);
            view.setText(CONTENT[position]);
            ((ViewPager)collection).addView(view);
            return view;
        }

        @Override
        public void destroyItem(View collection, int position, Object view) {
             ((ViewPager) collection).removeView((View) view);
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

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

        @Override
        public void restoreState(Parcelable arg0, ClassLoader arg1) {
        }

        @Override
        public void startUpdate(View arg0) {
        }

        @Override
        public void finishUpdate(View arg0) {
        }
}

I modified CirclePageIndicator.java created by JakeWharton to my use

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 float mPageOffset;
private int mScrollState;
private int mOrientation;
private boolean mCentered;

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

int mCount = 0;

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);


    //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);


    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;


     notifyDataSetChanged();

}

public boolean isCentered() {
    return mCentered;
}


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



    notifyDataSetChanged();
}

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);



    notifyDataSetChanged();
}

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

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



     notifyDataSetChanged();
}

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

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



     notifyDataSetChanged();
}

public float getRadius() {
    return mRadius;
}

boolean greaterThanFive  = false;
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if (mViewPager == null) {
        return;
    }
    //if(!greaterThanFive){
        mCount = mViewPager.getAdapter().getCount();
 //   }

        int condition=5;
        if(mCurrentPage>4)
            condition=2;

    if (mCount == 0) {
        return;
    }

    if (mCurrentPage >= mCount) {

       setCurrentItem(mCount-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) - ((condition * 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 < condition; 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= mCurrentPage* threeRadius;
    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;
}

@Override
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);
     notifyDataSetChanged();

}

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

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


    mViewPager.setCurrentItem(item);
    mCurrentPage = item;
     notifyDataSetChanged();

}

@Override
public void notifyDataSetChanged() {
    invalidate();
}


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

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

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

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

@Override
public void onPageSelected(int position) {
    /*if(position>4){
        mCount=2;
        greaterThanFive=true;
        mCurrentPage = position;

         notifyDataSetChanged();
        return;
    }*/
    if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
        mCurrentPage = position;
         notifyDataSetChanged();
    }

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

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

public void onExcessPage(){

}

/*
 * (non-Javadoc)
 *
 * @see android.view.View#onMeasure(int, int)
 */
@Override
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;
}

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

@Override
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();
    }

    @Override
    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>() {
        @Override
        public SavedState createFromParcel(Parcel in) {
            return new SavedState(in);
        }

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

PageIndicator .java

public interface PageIndicator extends ViewPager.OnPageChangeListener {

void setViewPager(ViewPager view);

void setViewPager(ViewPager view, int initialPosition);

void setCurrentItem(int item);

void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);

void notifyDataSetChanged();
}

My layout XML is

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

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="5dp"
    android:gravity="center_horizontal"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/btn_play"
        android:layout_width="90dp"
        android:layout_height="wrap_content"
        android:text="play" />

    <Button
        android:id="@+id/btn_pause"
        android:layout_width="90dp"
        android:layout_height="wrap_content"
        android:text="pause" />

    <Button
        android:id="@+id/btn_stop"
        android:layout_width="90dp"
        android:layout_height="wrap_content"
        android:text="stop" />
</LinearLayout>

<SeekBar
    android:id="@+id/seekBar"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="3dp" />

<android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    />

    <com.example.demopager.CirclePageIndicator
        android:id="@+id/indicator"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="10dip" />

 </LinearLayout>

Here you can see there is more than 10 pages in my pager .The thing i want to do id when i reach the 6th page i want to redraw the page indicator to 2 dots with out selection.

For first 5 Page changes it should be like this

After when i move to next page(page no >5) i want to avoid the selection of indicator and show only two indicators

Hope you understand what's my need (My English is not that good)..

So Please suggest me how can achieve this

Courtesy :Patrik Åkerfeldt & Jake Wharton

来源:https://stackoverflow.com/questions/14433281/android-fragment-pager-and-custom-page-indicator-viewpagerindicator-created-by

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!