网上有很多实现ViewPager图片无限轮播的方法,我这里使用的方法是设置adapter的count为整数最大,通过嵌套发送handler消息模拟实现ViewPager的无限轮播
1.将ViewPager和指示器(我这里用的是RadioGroup)封装到自定义的控件Banner里面
1.xml的配置
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="200dp">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<RadioGroup
android:id="@+id/radiogroup"
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="15dp"
android:gravity="center"
android:orientation="horizontal"></RadioGroup>
</RelativeLayout>
</merge>
2.代码的设置
View view = LayoutInflater.from(context).inflate(R.layout.banner_layout, this, true);
//滚动显示ViewPager
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
radioGroup = (RadioGroup) view.findViewById(R.id.radiogroup);
views = new LinkedList<>();
bannerAdapter = new BannerAdapter();
viewPager.setAdapter(bannerAdapter);
2.ViewPager适配器的设置(通过设置getCount的返回最大值虚拟实现ViewPager的无限轮播)
/**
* ViewPager的适配器
*/
class BannerAdapter extends PagerAdapter {
@Override
public int getCount() {
//将count设置成整数最大值,虚拟实现无线轮播
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(views.get(position % views.size()));
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = views.get(position % views.size());
ViewGroup parent = (ViewGroup) view.getParent();
//如果当前要显示的view有父布局先将父布局移除(view只能有一个父布局)
if (parent != null) {
parent.removeView(view);
}
container.addView(view);
return view;
}
}
3.设置ViewPager中显示的数据(根据轮播的图片数目实例化view布局和指示器radiobutton的个数)
public void setData(int... data) {
boolean isFirst = true;
int id[] = new int[data.length];
for (int i = 0; i < id.length; i++) {
id[i] = i;
}
for (int i = 0; i < data.length; i++) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.banner_item_layout, viewPager, false);
ImageView imageView = (ImageView) view.findViewById(R.id.iv_banner_item);
imageView.setImageResource(data[i]);
views.add(view);
//指示器小圆点的设置
View indicator = LayoutInflater.from(getContext()).inflate(R.layout.indicator_item_layout, viewPager, false);
radioButton = (RadioButton) indicator.findViewById(R.id.radioButton);
// 为radioButton设置一个id,不设置的话第一个radiobutton总是没法设置成选中中状态(不太清楚好像是个bug)
radioButton.setId(id[i]);
//将第一个指示器设置为选中
if (isFirst) {
radioButton.setChecked(true);
isFirst = false;
}
RadioGroup.LayoutParams layoutParams = new RadioGroup.LayoutParams(dip2px(getContext(), 10f), dip2px(getContext(), 10f));
layoutParams.leftMargin = dip2px(getContext(), 20);
radioGroup.addView(radioButton, layoutParams);
}
bannerAdapter.notifyDataSetChanged();
bannerPlay();
}
4.开启通过Handler嵌套发送消息实现ViewPager的轮播
public void bannerPlay() {
// 设置显示的初始位置,模拟向左无限滑动(设置合适的值就行,一般人也不会滑动很多)
pagerPosition = views.size() * 100;
if (handler == null) {
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
handler.post(new Runnable() {
@Override
public void run() {
viewPager.setCurrentItem(++pagerPosition);
}
});
Message message = handler.obtainMessage(0);
handler.sendMessageDelayed(message, 2000);
}
};
Message message = handler.obtainMessage(0);
handler.sendMessageDelayed(message, 2000);
}
}
5.监听ViewPager的滑动时间,实现指示器的状态同步
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//改变当前显示的pager的位置
pagerPosition = position;
position = position % views.size();
//改变被选中的指示器的状态
for (int i = 0; i < radioGroup.getChildCount(); i++) {
((RadioButton) radioGroup.getChildAt(i)).setChecked(i == position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
6.在程序中使用Banner实现图片的轮播效果
Banner banner = (Banner) findViewById(R.id.banner);
banner.setData(R.mipmap.ic_launcher,R.mipmap.ic_launcher, R.mipmap.ic_launcher,
R.mipmap.ic_launcher, R.mipmap.ic_launcher, R.mipmap.ic_launcher);
7.效果图