本文的内容通过标题可以看得出,是通过viewpager来滑动图片,同时还可以手动设置定时时间来实现自动播放,图片滑动的同时小红点指示器会跟随变化。先上效果图
上代码
1.Handler主要来处理手动跟自动之间的切换
public class MyHandler extends Handler {
private ViewPager viewPager;
/**
* 请求更新显示的View。
*/
protected static final int MSG_UPDATE_IMAGE = 1;
/**
* 请求暂停轮播。
*/
protected static final int MSG_KEEP_SILENT = 2;
/**
* 请求恢复轮播。
*/
protected static final int MSG_BREAK_SILENT = 3;
/**
* 记录最新的页号,当用户手动滑动时需要记录新页号,否则会使轮播的页面出错。
* 例如当前如果在第一页,本来准备播放的是第二页,而这时候用户滑动到了末页,
* 则应该播放的是第一页,如果继续按照原来的第二页播放,则逻辑上有问题。
*/
protected static final int MSG_PAGE_CHANGED = 4;
//轮播间隔时间
protected static final long MSG_DELAY = 1000;
private int currentItem = 0;
// protected //ImageHandler(WeakReference<MainActivity> wk){
// weakReference = wk;
// }
protected ImageHandler(ViewPager viewPager) {
this.viewPager = viewPager;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d("", "receive message " + msg.what);
//检查消息队列并移除未发送的消息,主要是避免在复杂环境下消息出现重复等问题。
if (hasMessages(MSG_UPDATE_IMAGE)) {
removeMessages(MSG_UPDATE_IMAGE);
}
switch (msg.what) {
case MSG_UPDATE_IMAGE:
currentItem++;
viewPager.setCurrentItem(currentItem);
//准备下次播放
sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
break;
case MSG_KEEP_SILENT:
//只要不发送消息就暂停了
break;
case MSG_BREAK_SILENT:
sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
break;
case MSG_PAGE_CHANGED:
//记录当前的页号,避免播放的时候页面显示不正确。
currentItem = msg.arg1;
break;
default:
break;
}
}
}
2.MainActivity的逻辑
public class MainActivity extends Activity {
private ArrayList<ImageView> imageViews;
private int[] imageResId; // 图片ID
private static final String LOG_TAG = "MainActivity";
private MyHandler handler;
private ViewPager viewPager;
private LinearLayout mLinearLayout;
private View mView;
private int diatance;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化iewPager的内容
viewPager = (ViewPager) findViewById(R.id.vp_pic);
mLinearLayout = (LinearLayout) findViewById(R.id.ll_points);
mView = findViewById(R.id.v_redpoint);
handler = new ImageHandler(viewPager);
initData();
viewPager.setAdapter(new ImageAdapter(imageViews));
/**
* 当底部红色小圆点加载完成时测出两个小灰点的距离,便于计算后面小红点动态移动的距离
*/
mView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
diatance = mLinearLayout.getChildAt(1).getLeft() - mLinearLayout.getChildAt(0).getLeft();
}
});
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
//配合Adapter的currentItem字段进行设置。
@Override
public void onPageSelected(int arg0) {
handler.sendMessage(Message.obtain(handler, ImageHandler.MSG_PAGE_CHANGED, arg0, 0));
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//测出页面滚动时小红点移动的距离,并通过setLayoutParams(params)不断更新其位置
position = position % imageViews.size();
float leftMargin = diatance * (position + positionOffset);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mView.getLayoutParams();
params.leftMargin = Math.round(leftMargin);
mView.setLayoutParams(params);
}
//覆写该方法实现轮播效果的暂停和恢复
@Override
public void onPageScrollStateChanged(int arg0) {
switch (arg0) {
case ViewPager.SCROLL_STATE_DRAGGING:
handler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);
break;
case ViewPager.SCROLL_STATE_IDLE:
handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
break;
default:
break;
}
}
});
viewPager.setCurrentItem(0);//默认在中间,使用户看不到边界
//开始轮播效果
handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
}
private void initData() {
imageViews = new ArrayList();
imageResId = new int[]{R.drawable.eo, R.drawable.eopard,
R.drawable.eo, R.drawable.eopard};
for (int i = 0; i < imageResId.length; i++) {
ImageView imageView = new ImageView(this);
imageView.setImageResource(imageResId[i]);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageViews.add(imageView);
//添加底部小黄点
View v = new View(getApplicationContext());
v.setBackgroundResource(R.drawable.yellow_circle);
//指定其大小
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20, 20);
if (i != 0)
params.leftMargin = 20;
v.setLayoutParams(params);
mLinearLayout.addView(v);
}
}
}
3.资源文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<android.support.v4.view.ViewPager
android:id="@+id/vp_pic"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v4.view.ViewPager>
<RelativeLayout
android:id="@+id/rl_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="45dip">
<LinearLayout
android:id="@+id/ll_points"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"></LinearLayout>
<View
android:id="@+id/v_redpoint"
android:layout_width="10dip"
android:layout_height="10dip"
android:background="@drawable/red_circle" />
</RelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#ff0000" />
<corners android:radius="5dip" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#effe33" />
<corners android:radius="5dip" />
</shape>