Android片段寻呼机和自定义页面指示器(由Jake Wharton创建的ViewPagerIndicator)

时间:2013-01-21 06:19:52

标签: android android-fragments android-viewpager android-pageradapter

我正在使用ViewPageIndicator来开发带有指标

的寻呼机视图

mycode的

活动

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) {
        }
}

我将JakeWharton创建的 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 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();
}

我的布局XML

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

在这里,您可以看到我的寻呼机中有超过10页。当我到达第6页时,我想要做的事情我想要将页面指示器重绘为2个点而没有选择。

对于前5页的更改,它应该是这样的

enter image description here

当我转到下一页(第5页 )后,我想避免选择指标并只显示两个指标

enter image description here

希望你明白我的需要(我的英语不是那么好)..

所以请建议我如何实现这个

礼貌:PatrikÅkerfeldt&amp;杰克沃顿

0 个答案:

没有答案