JakeWharton / ViewPagerIndicator

Paging indicator widgets compatible with the ViewPager from the Android Support Library and ActionBarSherlock.
http://viewpagerindicator.com
10.13k stars 4.01k forks source link

Change direction of bottom indicator #301

Open yazoury opened 10 years ago

yazoury commented 10 years ago

how can I change the direction of bottom indicator ,please guide me

idelgado commented 9 years ago

Changing the direction requires modifying the onDraw method and the onPageScrolled method. The onDraw method draws the rectangular indicator for the specific page. The onPageScrolled method defines the behavior of the indicator during a swipe.

I had to use reflection for the onDraw method since the members in the method are private. It is identical to the onDraw method of the UnderlinePageIndicator except that the currentPage is reversed.

Lastly, if you want to match the behavior in the ViewPager reverse your list of items and set the current item to size-1.

myPagerAdapter = new MyPagerAdapter(this, Lists.reverse(items));
myViewPager.setAdapter(myPagerAdapter);
myViewPager.setCurrentItem(items.size()-1);

Below is the ReversedUnderlinePageIndicator I described above.

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import com.viewpagerindicator.UnderlinePageIndicator;

import java.lang.reflect.Field;

public class ReversedUnderlinePageIndicator extends UnderlinePageIndicator {

    private ViewPager reflectedViewPager = null;
    private int reflectedCurrentPage = 0;
    private float reflectedPositionOffset = 0;
    private Paint reflectedPaint = null;

    public ReversedUnderlinePageIndicator(Context context) {
        super(context);
    }

    public ReversedUnderlinePageIndicator(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ReversedUnderlinePageIndicator(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    private void getPrivateArgsUsingReflection() {
        Field privateViewPager;
        Field privateCurrentPage;
        Field privatePositionOffset;
        Field privatePaint;
        try {
            privateViewPager = ReversedUnderlinePageIndicator.class.getSuperclass().getDeclaredField("mViewPager");
            privateViewPager.setAccessible(true);
            reflectedViewPager = (ViewPager) privateViewPager.get(this);
            privateCurrentPage = ReversedUnderlinePageIndicator.class.getSuperclass().getDeclaredField("mCurrentPage");
            privateCurrentPage.setAccessible(true);
            reflectedCurrentPage = (int) privateCurrentPage.get(this);
            privatePositionOffset = ReversedUnderlinePageIndicator.class.getSuperclass().getDeclaredField("mPositionOffset");
            privatePositionOffset.setAccessible(true);
            reflectedPositionOffset = (float) privatePositionOffset.get(this);
            privatePaint = ReversedUnderlinePageIndicator.class.getSuperclass().getDeclaredField("mPaint");
            privatePaint.setAccessible(true);
            reflectedPaint = (Paint) privatePaint.get(this);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    /*
     * This is identical to the onDraw method in the UnderlinePageIndicator except we reverse
     * the current page so that the indicator rectangle is drawn in the opposite location.
     * Reflection is used to access the private members in the UnderlinePageIndicator onDraw method.
     */
    @Override
    protected void onDraw(Canvas canvas) {
        getPrivateArgsUsingReflection();

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

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

        // Reverse the current page so that the rectangle is drawn in the opposite location
        reflectedCurrentPage = count - 1 - reflectedCurrentPage;

        final int paddingLeft = getPaddingLeft();
        final float pageWidth = (getWidth() - paddingLeft - getPaddingRight()) / (1f * count);
        final float left = paddingLeft + pageWidth * (reflectedCurrentPage + reflectedPositionOffset);
        final float right = left + pageWidth;
        final float top = getPaddingTop();
        final float bottom = getHeight() - getPaddingBottom();
        canvas.drawRect(left, top, right, bottom, reflectedPaint);
    }

    /*
     * Reverse the positionOffset so that scrolling moves in the opposite direction.
     */
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        super.onPageScrolled(position, -positionOffset, positionOffsetPixels);
    }

}