Android:Tab page indicator in view pager

user1025050 picture user1025050 · May 25, 2012 · Viewed 18.5k times · Source

I am making an application and I have to implement "sweepy tabs". I have read this but could not find anything relevant. I also tried ViewPagerIndicator.

Below is given my code snippet:

public class ViewPagerIndicatorActivity extends FragmentActivity {
PagerAdapter mPagerAdapter;
ViewPager  mViewPager;
ViewPagerIndicator mIndicator;
static ArrayList<String> readableDateFormat;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // Create our custom adapter to supply pages to the viewpager.
    mPagerAdapter = new PagerAdapter(getSupportFragmentManager());
    mViewPager = (ViewPager)findViewById(R.id.pager);
    mViewPager.setAdapter(mPagerAdapter);

    // Start at a custom position
    mViewPager.setCurrentItem(3);

    // Find the indicator from the layout
    mIndicator = (ViewPagerIndicator)findViewById(R.id.indicator);

    // Set the indicator as the pageChangeListener
    mViewPager.setOnPageChangeListener(mIndicator);

    // Initialize the indicator. We need some information here:
    // * What page do we start on.
    // * How many pages are there in total
    // * A callback to get page titles
    mIndicator.init(5, mPagerAdapter.getCount(), mPagerAdapter);
    Resources res = getResources();
    Drawable prev = res.getDrawable(R.drawable.indicator_prev_arrow);
    Drawable next = res.getDrawable(R.drawable.indicator_next_arrow);
    mIndicator.setFocusedTextColor(new int[]{255, 0, 0});

    // Set images for previous and next arrows.
    mIndicator.setArrows(prev, next);

    mIndicator.setOnClickListener(new OnIndicatorClickListener());
}

class OnIndicatorClickListener implements ViewPagerIndicator.OnClickListener{
    @Override
    public void onCurrentClicked(View v) {
        Toast.makeText(ViewPagerIndicatorActivity.this, "Hello", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onNextClicked(View v) {
        mViewPager.setCurrentItem(Math.min(mPagerAdapter.getCount() - 1, mIndicator.getCurrentPosition() + 1));
    }

    @Override
    public void onPreviousClicked(View v) {
        mViewPager.setCurrentItem(Math.max(0, mIndicator.getCurrentPosition() - 1));
    }

}

class PagerAdapter extends FragmentPagerAdapter implements ViewPagerIndicator.PageInfoProvider{
    public PagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int pos) {

        String list1[]={"Catagories","Latest","Most Downloaded","Top Paid"};

        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, pos - getCount() / 2);
        //return ItemFragment.newInstance(cal.getTime());
        return ItemFragment.newInstance1(list1);
    }

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

    @Override
    public String getTitle(int pos){
        String hello[]={"Catagories","Latest","Most Downloaded","Top Paid"};

        return hello.toString();
    }
}

public static class ItemFragment extends ListFragment{
    Date date;
    String[] hello1;

    static ItemFragment newInstance1(String[] hello) {
        ItemFragment f = new ItemFragment();

        // Supply num input as an argument.
        Bundle args = new Bundle();

        args.putStringArray("date", hello);
        f.setArguments(args);

        return f;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            this.hello1=list;
            System.out.println("hello:list -"+hello1);
        } catch (Exception e) {
            e.printStackTrace();

        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.date_fragment, container, false);
        View tv = v.findViewById(R.id.text);

        ((TextView)tv).setText(hello1.toString());

        System.out.println("text view :"+hello1.toString());

        return v;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setListAdapter(new ArrayAdapter<String>(getActivity(),
        android.R.layout.simple_list_item_1, list));
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        Log.i("FragmentList", "Item clicked: " + id);
    }
}

public static final String[] list = new String[]{"France", "London", "Sweden", "Denmark", "Germany", "Finland", "Thailand", "Taiwan", "USA", "Norway", "Denmark (again)", "Lithuania", "Bosnia", "Russia", "Vietnam", "Australia"};

} and other is :

public class ViewPagerIndicator extends RelativeLayout implements OnPageChangeListener {
private static final int PADDING = 5;

TextView mPrevious;
TextView mCurrent;
TextView mNext;
int mCurItem;
int mRestoreCurItem = -1;

LinearLayout mPreviousGroup;
LinearLayout mNextGroup;

int mArrowPadding;
int mSize;

ImageView mCurrentIndicator;
ImageView mPrevArrow;
ImageView mNextArrow;

int[] mFocusedTextColor;
int[] mUnfocusedTextColor;

OnClickListener mOnClickHandler;

public interface PageInfoProvider{
    String getTitle(int pos);
}

public interface OnClickListener{
    void onNextClicked(View v);
    void onPreviousClicked(View v);
    void onCurrentClicked(View v);
}

public void setOnClickListener(OnClickListener handler){
    this.mOnClickHandler = handler;
    mPreviousGroup.setOnClickListener(new OnPreviousClickedListener());
    mCurrent.setOnClickListener(new OnCurrentClickedListener());
    mNextGroup.setOnClickListener(new OnNextClickedListener());
}

public int getCurrentPosition(){
    return mCurItem;
}

PageInfoProvider mPageInfoProvider;
public void setPageInfoProvider(PageInfoProvider pageInfoProvider){
    this.mPageInfoProvider = pageInfoProvider;
}

public void setFocusedTextColor(int[] col){
    System.arraycopy(col, 0, mFocusedTextColor, 0, 3);
    updateColor(0);
}

public void setUnfocusedTextColor(int[] col){
    System.arraycopy(col, 0, mUnfocusedTextColor, 0, 3);
    mNext.setTextColor(Color.argb(255, col[0], col[1], col[2]));
    mPrevious.setTextColor(Color.argb(255, col[0], col[1], col[2]));
    updateColor(0);
}

@Override
protected Parcelable onSaveInstanceState() {
    Parcelable state = super.onSaveInstanceState();
    Bundle b = new Bundle();
    b.putInt("current", this.mCurItem);
    b.putParcelable("viewstate", state);
    return b;
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
    super.onRestoreInstanceState(((Bundle)state).getParcelable("viewstate"));
    mCurItem = ((Bundle)state).getInt("current", mCurItem);
    this.setText(mCurItem - 1);
    this.updateArrows(mCurItem);
    this.invalidate();
}

/**
 * Initialization
 * 
 * @param startPos The initially selected element in the ViewPager
 * @param size Total amount of elements in the ViewPager
 * @param pageInfoProvider Interface that returns page titles
 */
public void init(int startPos, int size, PageInfoProvider pageInfoProvider){
    setPageInfoProvider(pageInfoProvider);
    this.mSize = size;
    setText(startPos - 1);
    mCurItem = startPos;
}

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

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

public ViewPagerIndicator(Context context) {
    super(context);
    addContent();
}

/**
 * Add drawables for arrows
 * 
 * @param prev Left pointing arrow
 * @param next Right pointing arrow
 */
public void setArrows(Drawable prev, Drawable next){
    this.mPrevArrow = new ImageView(getContext());
    this.mPrevArrow.setImageDrawable(prev);

    this.mNextArrow = new ImageView(getContext());
    this.mNextArrow.setImageDrawable(next);

    LinearLayout.LayoutParams arrowLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    arrowLayoutParams.gravity = Gravity.CENTER;

    mPreviousGroup.removeAllViews();
    mPreviousGroup.addView(mPrevArrow, arrowLayoutParams);
    mPreviousGroup.addView(mPrevious, arrowLayoutParams);

    mPrevious.setPadding(PADDING, 0, 0, 0);
    mNext.setPadding(0, 0, PADDING, 0);

    mArrowPadding = PADDING + prev.getIntrinsicWidth();

    mNextGroup.addView(mNextArrow, arrowLayoutParams);
    updateArrows(mCurItem);
}

/**
 * Create all views, build the layout
 */
private void addContent(){
    mFocusedTextColor = new int[]{0, 0, 0};
    mUnfocusedTextColor = new int[]{190, 190, 190};

    // Text views
    mPrevious = new TextView(getContext());
    mCurrent = new TextView(getContext());
    mNext = new TextView(getContext());

    RelativeLayout.LayoutParams previousParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    previousParams.addRule(RelativeLayout.ALIGN_LEFT);

    RelativeLayout.LayoutParams currentParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    currentParams.addRule(RelativeLayout.CENTER_HORIZONTAL);

    RelativeLayout.LayoutParams nextParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    nextParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);

    // Groups holding text and arrows
    mPreviousGroup = new LinearLayout(getContext());
    mPreviousGroup.setOrientation(LinearLayout.HORIZONTAL);
    mNextGroup = new LinearLayout(getContext());
    mNextGroup.setOrientation(LinearLayout.HORIZONTAL);

    mPreviousGroup.addView(mPrevious, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    mNextGroup.addView(mNext, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

    addView(mPreviousGroup, previousParams);
    addView(mCurrent, currentParams);
    addView(mNextGroup, nextParams);

    mPrevious.setSingleLine();
    mCurrent.setSingleLine();
    mNext.setSingleLine();

    mPrevious.setText("previous");
    mCurrent.setText("current");
    mNext.setText("next");

    mPrevious.setClickable(false);
    mNext.setClickable(false);
    mCurrent.setClickable(true);
    mPreviousGroup.setClickable(true);
    mNextGroup.setClickable(true);

    // Set colors
    mNext.setTextColor(Color.argb(255, mUnfocusedTextColor[0], mUnfocusedTextColor[1], mUnfocusedTextColor[2]));
    mPrevious.setTextColor(Color.argb(255, mUnfocusedTextColor[0], mUnfocusedTextColor[1], mUnfocusedTextColor[2]));
    updateColor(0);
}

@Override
public void onPageScrollStateChanged(int state) {

}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    positionOffsetPixels = adjustOffset(positionOffsetPixels);
    position = updatePosition(position, positionOffsetPixels);
    setText(position - 1);
    updateColor(positionOffsetPixels);
    updateArrows(position);
    updatePositions(positionOffsetPixels);
    mCurItem = position;
}

void updatePositions(int positionOffsetPixels){
    int textWidth = mCurrent.getWidth() - mCurrent.getPaddingLeft() - mCurrent.getPaddingRight();
    int maxOffset = this.getWidth() / 2 - textWidth / 2 - mArrowPadding;
    if(positionOffsetPixels > 0){
        maxOffset -= this.getPaddingLeft();
        int offset = Math.min(positionOffsetPixels, maxOffset - 1);
        mCurrent.setPadding(0, 0, 2 * offset, 0);

        // Move previous text out of the way. Slightly buggy.
        /*
        int overlapLeft = mPreviousGroup.getRight() - mCurrent.getLeft() + mArrowPadding;
        mPreviousGroup.setPadding(0, 0, Math.max(0, overlapLeft), 0);
        mNextGroup.setPadding(0, 0, 0, 0);
        */
    }else{
        maxOffset -= this.getPaddingRight();
        int offset = Math.max(positionOffsetPixels, -maxOffset);
        mCurrent.setPadding(-2 * offset, 0, 0, 0);

        // Move next text out of the way. Slightly buggy.
        /*
        int overlapRight = mCurrent.getRight() - mNextGroup.getLeft() + mArrowPadding;
        mNextGroup.setPadding(Math.max(0, overlapRight), 0, 0, 0);
        mPreviousGroup.setPadding(0, 0, 0, 0);
        */
    }
}

/**
 * Hide arrows if we can't scroll further
 * 
 * @param position
 */
void updateArrows(int position){
    if(mPrevArrow != null){
        mPrevArrow.setVisibility(position == 0 ? View.INVISIBLE : View.VISIBLE);
        mNextArrow.setVisibility(position == mSize - 1 ? View.INVISIBLE : View.VISIBLE);
    }
}

/**
 * Adjust position to be the view that is showing the most.
 * 
 * @param givenPosition
 * @param offset
 * @return
 */
int updatePosition(int givenPosition, int offset){
    int pos;
    if(offset < 0){
        pos = givenPosition + 1;
    }else{
        pos = givenPosition;
    }
    return pos; 
}

/**
 * Fade "currently showing" color depending on it's position
 * 
 * @param offset
 */
void updateColor(int offset){
    offset = Math.abs(offset);
    // Initial condition: offset is always 0, this.getWidth is also 0! 0/0 = NaN
    int width = this.getWidth();
    float fraction = width == 0 ? 0 : offset / ((float)width / 4.0f);
    fraction = Math.min(1, fraction);
    int r = (int)(mUnfocusedTextColor[0] * fraction + mFocusedTextColor[0] * (1 - fraction));
    int g = (int)(mUnfocusedTextColor[1] * fraction + mFocusedTextColor[1] * (1 - fraction));
    int b = (int)(mUnfocusedTextColor[2] * fraction + mFocusedTextColor[2] * (1 - fraction));
    mCurrent.setTextColor(Color.argb(255, r, g, b));
}

/**
 * Update text depending on it's position
 * 
 * @param prevPos
 */
void setText(int prevPos){
    if(prevPos < 0){
        mPrevious.setText("");
    }else{
        mPrevious.setText(mPageInfoProvider.getTitle(prevPos));
    }
    mCurrent.setText(mPageInfoProvider.getTitle(prevPos + 1));
    String hellolo= ("current"+mPageInfoProvider.getTitle(prevPos + 1));
    if(prevPos + 2 == this.mSize){
        mNext.setText("");
    }else{
        mNext.setText(mPageInfoProvider.getTitle(prevPos + 2));
    }
}

// Original:
// 244, 245, 0, 1, 2
// New:
// -2, -1, 0, 1, 2
int adjustOffset(int positionOffsetPixels){
    // Move offset half width
    positionOffsetPixels += this.getWidth() / 2;
    // Clamp to width
    positionOffsetPixels %= this.getWidth();
    // Center around zero
    positionOffsetPixels -= this.getWidth() / 2;
    return positionOffsetPixels;
}

@Override
public void onPageSelected(int position) {
    // Reset padding when the page is finally selected (May not be necessary)
    mCurrent.setPadding(0, 0, 0, 0);
}

class OnPreviousClickedListener implements android.view.View.OnClickListener{
    @Override
    public void onClick(View v) {
        if(mOnClickHandler != null){
            mOnClickHandler.onPreviousClicked(ViewPagerIndicator.this);
        }
    }
}
class OnCurrentClickedListener implements android.view.View.OnClickListener{
    @Override
    public void onClick(View v) {
        if(mOnClickHandler != null){
            mOnClickHandler.onCurrentClicked(ViewPagerIndicator.this);
        }
    }
}
class OnNextClickedListener implements android.view.View.OnClickListener{
    @Override
    public void onClick(View v) {
        if(mOnClickHandler != null){
            mOnClickHandler.onNextClicked(ViewPagerIndicator.this);
        }
    }
}

} and instead of name i getting Ljava.lang.String@44daf8enter image description here

Any help regarding this will be helpful.

Answer

Alex Lockwood picture Alex Lockwood · May 26, 2012

The "sweepy tabs" you are referring to is actually just a ViewPager with corresponding title tabs for each page. This is not included in the Android SDK by default, but you can use Jake Wharton's ViewPagerIndicator to add the titles for each tab in your ViewPager.

Jake Wharton has supplied a bunch of sample code on GitHub, which you should take a look at. If you have already implemented your ViewPager, changing your code so that it makes use of the TabPagerIndicator (the class that will add the titles for your tabs) won't be too difficult at all. You can also refer to the usage section on the Jake Wharton's site.

I feel like this is more than enough to ensure that you implement your ViewPager correctly, but feel free to ask any questions if something comes up.