2012-11-26 31 views
7

Tôi đang sử dụng ví dụ của Jake Wharton để hiển thị chỉ báo chế độ xem. www.viewpagerindicator.comXem chỉ báo máy nhắn tin Jake Wharton

Tôi đang sử dụng chỉ báo vòng tròn chụp nhanh.

ai cũng có thể cho tôi biết cách tăng chiều rộng giữa các vòng kết nối?

Thông số nào phải được thay đổi?

+2

Tôi đã tìm thấy giải pháp. Nó có thể giúp bạn. Chúng tôi cần tăng thông số "baRadius" lên giá trị cao hơn. Cảm ơn. – Ajitha

+0

Bạn có thể đăng giải pháp làm câu trả lời. –

+0

Cảm ơn bạn thân. làm tương tự. – Ajitha

Trả lời

3

Bạn có thể tìm tất cả tham số trong tệp res/values ​​/ vpi_attrs.xml. Kiểu kết hợp của CirclePageIndicator được chỉ định:

<!-- Radius of the circles. This is also the spacing between circles. --> 
<attr name="radius" format="dimension" /> 

Không thể thay đổi khoảng cách giữa hai vòng tròn. Bạn phải phân lớp CirclePageIndicator:

  • tạo YourCirclePageIndicator trong dự án của bạn
  • thêm một attribut gapCircle mới
  • override onDraw phương pháp và thay đổi tính toán của shortOffset/longOffset
+0

Cảm ơn rất nhiều. Tôi đã đăng giải pháp đóng bên dưới. – Ajitha

13

Chúng tôi cần phải tăng " baRadius "tham số giá trị cao hơn. Cảm ơn.

+1

Điều này làm việc cho tôi. Tôi đã thay đổi biến baRadius từ mRadius * 3 thành mRadius * 5 và điều này đã thực hiện thủ thuật. Cảm ơn. – azdragon2

+0

hii tôi đang gặp vấn đề tương tự. nơi chính xác tôi sẽ tìm thấy baRadius paramatere? – iMDroid

+0

biến ba bán kính này bạn có thể tìm thấy trong phương thức onDraw của lớp CirclePageIndicator. – yasiriqbal776

1

Gọi CirclePageIndicator.setRadius()

1

Tôi biết đây là một câu hỏi cũ, nhưng đối với những người khác có thể chạy vào vấn đề này trong tương lai, tôi nghĩ rằng tôi tốt hơn muốn đăng nó.
Chỉ cần tăng thông số "baRadius" lên giá trị cao hơn sẽ không làm, bởi vì nó làm rối loạn tâm của vòng tròn.

Vì vậy, đây là một phiên bản sửa đổi của CirclePageIndicator lớp:

import android.content.Context; 
import android.content.res.Resources; 
import android.content.res.TypedArray; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Paint.Style; 
import android.graphics.drawable.Drawable; 
import android.os.Parcel; 
import android.os.Parcelable; 
import android.support.v4.view.MotionEventCompat; 
import android.support.v4.view.ViewConfigurationCompat; 
import android.support.v4.view.ViewPager; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.ViewConfiguration; 

import com.viewpagerindicator.PageIndicator; 

import static android.graphics.Paint.ANTI_ALIAS_FLAG; 
import static android.widget.LinearLayout.HORIZONTAL; 
import static android.widget.LinearLayout.VERTICAL; 


/** 
* Draws circles (one for each view). The current view position is filled and 
* others are only stroked. 
*/ 
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; 
    private int distanceBetweenCircles = 20; 


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

     distanceBetweenCircles = getResources().getDimensionPixelSize(R.dimen._40); 

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

    @Override 
    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 shortPaddingBefore; 
     if (mOrientation == HORIZONTAL) { 
      longSize = getWidth(); 
      shortPaddingBefore = getPaddingTop(); 
     } else { 
      longSize = getHeight(); 
      shortPaddingBefore = getPaddingLeft(); 
     } 

     final float neededSpaceForCircles = (mRadius * 2 * count + distanceBetweenCircles * (count - 1)); 
     final float startX = (longSize - neededSpaceForCircles)/2f + mRadius; 
     final float shortOffset = shortPaddingBefore + mRadius; 

     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 = startX + iLoop * (distanceBetweenCircles + 2 * mRadius); 

      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) * (distanceBetweenCircles + 2 * mRadius); 
     if (!mSnap) { 
      cx += mPageOffset * distanceBetweenCircles; 
     } 
     if (mOrientation == HORIZONTAL) { 
      dX = startX + cx; 
      dY = shortOffset; 
     } else { 
      dX = shortOffset; 
      dY = startX + 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); 
     invalidate(); 
    } 

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

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

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

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

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

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

    /* 
    * (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; 
     mSnapPage = 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]; 
      } 
     }; 
    } 
} 

Thông báo dòng

distanceBetweenCircles = getResources().getDimensionPixelSize(R.dimen._40); 

Để thay đổi khoảng cách, chỉ cần thay đổi giá trị của distanceBetweenCircles. Tôi mã hóa nó bởi vì tôi luôn cần khoảng cách tương tự trong tất cả các quan điểm của mình.

-1

sở hữu Sử dụng tùy chỉnh gapWidth

<com.viewpagerindicator.CirclePageIndicator 
    android:id="@+id/indicator" 
    android:padding="@dimen/activity_padding" 
    android:layout_gravity="center_horizontal|bottom" 
    android:layout_margin="@dimen/tutorial_indicator_margin" 
    android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:background="#00000000" 
    app:gapWidth="24dp"/> 

Đừng quên để thêm xmlns:app="http://schemas.android.com/apk/res-auto" để bố trí cha mẹ của bạn.

Các vấn đề liên quan