很久没更新博客了,发现自己变懒了,这可不是好现象,今天带来快速打造ViewPagerIndicator的教程,老规矩还是先上图吧。![demo](https://img-blog.csdn.net/20150521115937567)
可以看到上面部分的的Indicator可以满足我们大部分的需求。那么我们就来快速打造这样的一个Indicator首先观察上部是几个textview和一个view通过linearlayout组合起来,最主要的就是怎么改变下标的滑动。
话不多说直接上代码。`
/***
* Copyright (c) 2015, TNT All Rights Reserved.
*
* @author bobo
* @date 2015-5-19
* @filename PagerIndicator.java
*
*
*/
public class PagerIndicator extends LinearLayout implements OnClickListener, OnPageChangeListener
{
private int mIndicatorWidth = 0; // 指示器宽度
private List<String> mPagerTitles;// 标题
private List<TextView> mIndicatorStringViews;// 指示器标题views
private View mIndicatorView; // 指示器view
private ViewPager mviewpager;// viewpager
PagerIndicatorListener mPagerIndicatorListener; // 对外保留的监听器
private int mIndicatorNormalColor = Color.BLACK;// 默认的未选中颜色
private int mIndicatorSelectlColor = Color.BLUE;// 选中的颜色
public PagerIndicator(Context context)
{
super(context);
}
public PagerIndicator(Context context, AttributeSet attrs)
{
super(context, attrs);
}
/***
* 设置监听
*
* @param mPagerIndicatorListener
*/
public void setPagerIndicatorListener(PagerIndicatorListener mPagerIndicatorListener)
{
this.mPagerIndicatorListener = mPagerIndicatorListener;
}
/***
* 设置选中第几个
*
* @param viewPager
* @param defaultPager
*/
public void setViewPager(ViewPager viewPager, int defaultPager)
{
this.mviewpager = viewPager;
buildIndicator();
startDefaultPagers();
changeState(defaultPager);
}
/***
* 同理设置viewpager
*
* @param mviewpager
*/
public void setViewpager(ViewPager mviewpager)
{
setViewPager(mviewpager, 0);
}
/**
* 开启监听
*/
private void startDefaultPagers()
{
mviewpager.setOnPageChangeListener(this);
}
/***
* 构建指示器
*/
private void buildIndicator()
{
if (mIndicatorStringViews == null)
{
mIndicatorStringViews = new ArrayList<TextView>();
}
setOrientation(LinearLayout.VERTICAL);
LinearLayout indicatorStringViewRoot = new LinearLayout(getContext()); // 标题的view
indicatorStringViewRoot.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
indicatorStringViewRoot.setOrientation(LinearLayout.HORIZONTAL);
if (mPagerTitles != null)
{
for (int i = 0; i < mPagerTitles.size(); i++)
{
TextView pagerIndicatorStringView = new TextView(getContext());
pagerIndicatorStringView.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1));
pagerIndicatorStringView.setGravity(Gravity.CENTER);
pagerIndicatorStringView.setText(mPagerTitles.get(i));
pagerIndicatorStringView.setTextColor(mIndicatorNormalColor);
pagerIndicatorStringView.setTag(i); // 设置tag为了监听的时候区分第几个
pagerIndicatorStringView.setClickable(true);
pagerIndicatorStringView.setOnClickListener(this);
indicatorStringViewRoot.addView(pagerIndicatorStringView);
mIndicatorStringViews.add(pagerIndicatorStringView);
}
addView(indicatorStringViewRoot);// 添加标题的View
mIndicatorView = new View(getContext());// 构建指示器view
mIndicatorView.setBackgroundColor(mIndicatorSelectlColor);
mIndicatorWidth = getResources().getDisplayMetrics().widthPixels / mPagerTitles.size();// 计算宽度
mIndicatorView.setLayoutParams(new LayoutParams(mIndicatorWidth, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics())));
addView(mIndicatorView);// 添加指示器
}
}
/***
* 添加indicator
*
* @param indicator
*/
public void addIndicator(String indicator)
{
if (mPagerTitles == null)
{
mPagerTitles = new ArrayList<String>();
}
mPagerTitles.add(indicator);
}
/**
* 更具选中的index来改变显示的状态
*
* @param index
*/
private void changeState(int index)
{
for (int i = 0; i < mIndicatorStringViews.size(); i++)
{
if (i == index)
{
mIndicatorStringViews.get(i).setTextColor(mIndicatorSelectlColor);
mviewpager.setCurrentItem(i);
}
else
{
mIndicatorStringViews.get(i).setTextColor(mIndicatorNormalColor);
}
}
}
@Override
public void onClick(View v)
{
changeState((Integer) v.getTag());
// mclickMode = INDICATOR_VIEW;
}
@Override
public void onPageScrollStateChanged(int state)
{
if (mPagerIndicatorListener != null)
{
mPagerIndicatorListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
if (mPagerIndicatorListener != null)
{
mPagerIndicatorListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
float translationX = (mIndicatorWidth * (position + positionOffset));// 计算需要移动多少距离
mIndicatorView.setTranslationX(translationX); // 采用tanslationx来实现指示器view的移动
}
@Override
public void onPageSelected(int position)
{
changeState(position);// 改变状态
if (mPagerIndicatorListener != null)
{
mPagerIndicatorListener.onPageSelected(position);
}
}
}
`可以看到我们继承自LinearLayout对外暴露了addIndicator这个方法和setViewPager方法,addIndicator方法就是添加一个Indicator,在buildIndicator这个方法里面构建界面,还有就是由于viewpager的PageChangeListener接口被我们使用 就需要对外在提供一个这样的接口,同样最重要的移动代码就是setTranslationX(translationX); 利用了3.0以上的属性动画。代码注释都很多久不解释了,下面贴出对外暴露试页面怎么写的。
/***
*
* Copyright (c) 2015, TNT All Rights Reserved.
*
* @author bobo
* @date 2015-5-19
* @filename PagerIndicatorListener.java
*
*/
public interface PagerIndicatorListener
{
public void onPageScrollStateChanged(int state);
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
public void onPageSelected(int index);
}
先给出xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.bobo.pagerIndicator.PagerIndicator
android:id="@+id/pagerIndicator"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</com.bobo.pagerIndicator.PagerIndicator>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
</LinearLayout>
然后是activity里面的oncreate代码
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.demo);
PagerIndicator pagerIndicator = (PagerIndicator) findViewById(R.id.pagerIndicator);
pagerIndicator.addIndicator("第一页");
pagerIndicator.addIndicator("第二页");
pagerIndicator.addIndicator("第三页");
pagerIndicator.addIndicator("第四页");
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new PagerAdapter()
{
@Override
public Object instantiateItem(ViewGroup container, int position)
{
TextView textView = new TextView(MainActivity.this);
textView.setTextSize(18);
textView.setGravity(Gravity.CENTER);
container.addView(textView);
textView.setText("这是第"+(position+1)+"页");
return textView;
// return super.instantiateItem(container, position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object)
{
// TODO Auto-generated method stub
// super.destroyItem(container, position, object);
container.removeView((TextView)object);
}
@Override
public boolean isViewFromObject(View arg0, Object arg1)
{
return arg0==arg1;
}
@Override
public int getCount()
{
return 4;
}
});
pagerIndicator.setViewpager(viewPager);
}
给出demo的下载地址:传送门