天は二物を与えず
ViewPager是Android提供的一个良心组件,有了它分分钟就可以实现了一个水平滑动的分页功能,其中用ViewPager来全屏展示图片是一个比较经典的使用场景,先来看一下效果图:
在每个Page的底部中间位置有一排圆圈,实心的圆圈用来指示当前显示的图片,它会随着手指滑动而移动,我们可以称之为 ViewPager 的 indicator。
实现这个功能也比较简单,首先定义一个水平方向的LinearLayout用来显示 indicator,然后把这个LinearLayout和ViewPager作为子元素放在一个FrameLayout中,这样 indicator 的 LinearLayout 会在显示在 ViewPager 的上层,初步达到了显示效果,但是滑动效果还没有实现。
首先新建一个LinearLayout的子类 - CirclePageIndicator
public class CirclePageIndicator extends LinearLayout
如果要优雅地实现这个类,可以参考Android中如何优雅地自定义一个View。
根据 ViewPager 的 page 数添加 indicator, 这里先定义好这个方法,等到后看再用。
private void addIndicator(int count) {
for (int i = 0; i < count; i++) {
ImageView img = new ImageView(getContext());
LayoutParams params = new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.leftMargin = indicatorSpacing;
params.rightMargin = indicatorSpacing;
img.setImageResource(R.drawable.circle_indicator_stroke);
addView(img, params);
}
if (count > 0) {
((ImageView) getChildAt(0)).setImageResource(R.drawable.circle_indicator_solid);
}
}
我希望 CirclePageIndicator 的用法足够简单,简单到只需要一条语句就可以把它附加到 ViewPager 上。
CirclePageIndicator indicator = (CirclePageIndicator) findViewById(R.id.indicator);
indicator.setViewPager(pager);
那么我们就为 CirclePageIndicator 添加 setViewPager 方法。
public void setViewPager(ViewPager pager) {
userDefinedPageChangeListener = getOnPageChangeListener(pager);
pager.setOnPageChangeListener(this);
addIndicator(pager.getAdapter().getCount());
}
为了能监听 ViewPager 中 PageChange 时间,让 CirclePageIndicator 实现了 ViewPager.OnPageChangeListener 这个接口,然后在 setViewPager 的时候,为 ViewPager 添加这个 listener。
但是,这样问题又来了,如果 ViewPager 在传入之前已经有了 listener ,这里很显然会把之前的 listener 给覆盖掉,这个也好办,稍微 hack 一下,用反射把之前的 listener 拿到就可以了。
private ViewPager.OnPageChangeListener getOnPageChangeListener(ViewPager pager) {
try {
Field f = pager.getClass().getDeclaredField("mOnPageChangeListener");
f.setAccessible(true);
return (ViewPager.OnPageChangeListener) f.get(pager);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
剩下的把 ViewPager.OnPageChangeListener
中的方法实现一下,根据 page 的变化更新 indicator 就完成了。
原文地址:http://blog.csdn.net/feelang/article/details/45054795