首先,让我们了解下什么是viewpager:
这个大致意思是:这个布局管理器允许用户左右翻转并传递页面的数据,你想要的视图可以通过pagerAdapter来实现。
布局文件很简单,只有个用于展示图片的viewpager和用于同步展示图片的radioGroup
pagerAdapter是android.support.v4包中的类,它的子类有fragmentPagerAdapter、 fragmentStatePagerAdapter,这两个adapter都是fragment的适配器,用于实现fragment的滑动效果。
PagerAdapter pagerAdapter = new PagerAdapter() {
@Override
public int getCount() {
return Integer.MAX_VALUE;
// return images.length;
}
@Override
public boolean isViewFromObject(View view, Object object) {
//判断当前要显示的画面
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
position = position % images.length;
ImageView imageView = new ImageView(ViewPagerActivity.this);
imageView.setImageResource(images[position]);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
container.addView(imageView);
return imageView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
};
pagerAdapter内有四个方法:
getCount():要滑动的图片数量,这里用Integer.MAX_VALUE,目的是为了实现无限轮播。
isViewFromObject():这个方法用于判断当前要显示的图片。
instantiateItem():调用这个方法用于图片初始化,将要显示的图片放到container中缓存,viewpager的setOffscreenPageLimit()方法用于设置缓存图片的数量。
destroyItem():当滑动的图片超出缓存范围,就会销毁缓存的图片。
viewPager的pageTransformer是滑动图片的一个动画效果,viewPager提供setPageTransformer()这个方法用于设置动画。
public class PageTransform implements ViewPager.PageTransformer {
@Override
public void transformPage(View view, float position) {
if (position < -1) {
//透明度
view.setAlpha(mMinAlpha);
//旋转
view.setRotation(mMaxRotate * -1);
view.setPivotX(view.getWidth());
view.setPivotY(view.getHeight());
} else if (position <= 1) {
if (position < 0) {
//position是0到-1的变化,1+position就是从1到0的变化
//(1 - mMinAlpha) * (1 + position)就是(1 - mMinAlpha)到0的变化
//再加上一个mMinAlpha,就变为1到mMinAlpha的变化。
float factor = mMinAlpha + (1 - mMinAlpha) * (1 + position);
view.setAlpha(factor);
view.setRotation(mMaxRotate * position);
//position为width/2到width的变化
view.setPivotX(view.getWidth() * 0.5f * (1 - position));
view.setPivotY(view.getHeight());
} else {
//minAlpha到1的变化
float factor = mMinAlpha + (1 - mMinAlpha) * (1 - position);
view.setAlpha(factor);
view.setRotation(mMaxRotate * position);
view.setPivotX(view.getWidth() * 0.5f * (1 - position));
view.setPivotY(view.getHeight());
}
} else {
view.setAlpha(mMinAlpha);
view.setRotation(mMaxRotate);
view.setPivotX(0);
view.setPivotY(view.getHeight());
}
}
}
private void initRadioButton(int length) {
for (int i = 0; i < length; i++) {
ImageView imageView = new ImageView(ViewPagerActivity.this);
imageView.setImageResource(R.drawable.rg_selector);
imageView.setPadding(20, 0, 0, 0);
radioGroup.addView(imageView, ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
radioGroup.getChildAt(0).setEnabled(false);
}
}
length就是轮播图片的数量。
rg_selctor: state_enabled:是否处于可用状态
rb_default:
rb_select:
ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
index = position;
setCurrentDot(index % images.length);
}
@Override
public void onPageScrollStateChanged(int state) {
}
};
private void setCurrentDot(int i) {
if (radioGroup.getChildAt(i) != null) {
//当前按钮不可改变
radioGroup.getChildAt(i).setEnabled(false);
}
if (radioGroup.getChildAt(preIndex) != null) {
//上个按钮可以改变
radioGroup.getChildAt(preIndex).setEnabled(true);
//当前位置变为上一个,继续下次轮播
preIndex = i;
}
}
timer.schedule(new TimerTask() {
@Override
public void run() {
if (isContinue) {
handler.sendEmptyMessage(1);
}
}
}, 2000, 2000);
schedule()方法第三个参数是图片轮播完后多久再次执行run()方法,这里设置两秒,跟延时一致,图片会完美轮播下去。
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
index++;
viewPager.setCurrentItem(index);
}
}
};
handler调用handleMessage()方法处理消息。
public class ViewPagerActivity extends AppCompatActivity {
private ViewPager viewPager;
private int images[] = {R.drawable.img01, R.drawable.img02, R.drawable.img03,
R.drawable.img04, R.drawable.img05, R.drawable.img06};
private RadioGroup radioGroup;
//当前索引位置以及上一个索引位置
private int index;
private int preIndex;
private Timer timer = new Timer();
//是否需要轮播标志
private boolean isContinue = true;
private static final float DEFAULT_MIN_ALPHA = 0.3f;
private float mMinAlpha = DEFAULT_MIN_ALPHA;
private static final float DEFAULT_MAX_ROTATE = 15.0f;
private float mMaxRotate = DEFAULT_MAX_ROTATE;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_image);
viewPager = (ViewPager) findViewById(R.id.view_Pager);
radioGroup = (RadioGroup) findViewById(R.id.radio_group);
//设置page之间间距
viewPager.setPageMargin(30);
//设置缓存的页面数量
viewPager.setOffscreenPageLimit(3);
viewPager.setAdapter(pagerAdapter);
viewPager.addOnPageChangeListener(onPageChangeListener);
viewPager.setPageTransformer(true, new PageTransform());
viewPager.setCurrentItem(images.length * 100);
initRadioButton(images.length);
timer.schedule(new TimerTask() {
@Override
public void run() {
if (isContinue) {
handler.sendEmptyMessage(1);
}
}
}, 2000, 2000);
}
PagerAdapter pagerAdapter = new PagerAdapter() {
@Override
public int getCount() {
return Integer.MAX_VALUE;
// return images.length;
}
@Override
public boolean isViewFromObject(View view, Object object) {
//判断当前要显示的画面
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
position = position % images.length;
ImageView imageView = new ImageView(ViewPagerActivity.this);
imageView.setImageResource(images[position]);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
container.addView(imageView);
return imageView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
};
/**
* [-Infinity,-1)(1,+Infinity][-1,1]
* 三个区间,对于前两个,拿我们的页面上目前显示的3个Page来说,前两个分别对应左右两个露出一点的Page,
* 那么对于alpha值,只需要设置为最小值即可
*
* [-1,1]第一页->第二页这个过程来说,主要看position的变化
* 页1的position变化为:从0到-1, 页2的position变化为:从1到0
* 第一页到第二页,实际上就是左滑,第一页到左边,第二页成为currentItem到达中间,
* 那么对应alpha的变化应该是:页1到左边,对应alpha应该是:1到minAlpha
* 页2到中间,成为currentItem,对应alpha应该是:minAlpha到1
*/
public class PageTransform implements ViewPager.PageTransformer {
@Override
public void transformPage(View view, float position) {
if (position < -1) {
//透明度
view.setAlpha(mMinAlpha);
//旋转
view.setRotation(mMaxRotate * -1);
view.setPivotX(view.getWidth());
view.setPivotY(view.getHeight());
} else if (position <= 1) {
if (position < 0) {
//position是0到-1的变化,1+position就是从1到0的变化
//(1 - mMinAlpha) * (1 + position)就是(1 - mMinAlpha)到0的变化
//再加上一个mMinAlpha,就变为1到mMinAlpha的变化。
float factor = mMinAlpha + (1 - mMinAlpha) * (1 + position);
view.setAlpha(factor);
view.setRotation(mMaxRotate * position);
//position为width/2到width的变化
view.setPivotX(view.getWidth() * 0.5f * (1 - position));
view.setPivotY(view.getHeight());
} else {
//minAlpha到1的变化
float factor = mMinAlpha + (1 - mMinAlpha) * (1 - position);
view.setAlpha(factor);
view.setRotation(mMaxRotate * position);
view.setPivotX(view.getWidth() * 0.5f * (1 - position));
view.setPivotY(view.getHeight());
}
} else {
view.setAlpha(mMinAlpha);
view.setRotation(mMaxRotate);
view.setPivotX(0);
view.setPivotY(view.getHeight());
}
}
}
private void initRadioButton(int length) {
for (int i = 0; i < length; i++) {
ImageView imageView = new ImageView(ViewPagerActivity.this);
imageView.setImageResource(R.drawable.rg_selector);
imageView.setPadding(20, 0, 0, 0);
radioGroup.addView(imageView, ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
radioGroup.getChildAt(0).setEnabled(false);
}
}
ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
index = position;
setCurrentDot(index % images.length);
}
@Override
public void onPageScrollStateChanged(int state) {
}
};
private void setCurrentDot(int i) {
if (radioGroup.getChildAt(i) != null) {
//当前按钮不可改变
radioGroup.getChildAt(i).setEnabled(false);
}
if (radioGroup.getChildAt(preIndex) != null) {
//上个按钮可以改变
radioGroup.getChildAt(preIndex).setEnabled(true);
//当前位置变为上一个,继续下次轮播
preIndex = i;
}
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
index++;
viewPager.setCurrentItem(index);
}
}
};
}