在app中使用轮播图可以用来插入广告或者轮替显示图片信息,比较美观,所以要是某个页面感觉空空的,加上轮播图就能去掉留白,让页面看起来更加充实,本篇主要记录使用ViewPager和定时任务实现轮播图。
一、布局准备
首先在drawable文件夹中新建xml文件对应轮播图中图片标记点的两种状态,当翻页到指定页面时,对应位置的标记点颜色为深色,其他点颜色为浅色。
drawable/dot_normal.xml:
xml version="1.0" encoding="utf-8"?>
<!--正常状态-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<corners android:radius="5dip"/>
<solid android:color="#aaFFFFFF"/>
</shape>
drawable/dot_focused.xml:
<?xml version="1.0" encoding="utf-8"?>
<!--指定状态-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<corners android:radius="5dip"/>
<solid android:color="#55000000"/>
</shape>
然后在value文件夹中新建资源文件id.xml,这样之后才能根据图片设置的id建立点击事件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="pager_image1" type="id" />
<item name="pager_image2" type="id" />
<item name="pager_image3" type="id" />
<item name="pager_image4" type="id" />
<item name="pager_image5" type="id" />
</resources>
在layout布局中加入ViewPager用于显示可翻页的图片背景和标记点
<!--轮播图布局容器-->
<FrameLayout
android:id="@+id/fl"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--轮播图控件-->
<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="160dp"/>
<!--小点以及文字布局容器-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_gravity="bottom"
android:background="#33000000"
android:gravity="center_vertical"
android:orientation="horizontal">
<!--轮播图文字-->
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="8"
android:text="图片标题"
android:textColor="#fff"/>
<!--小点布局-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="center_vertical"
android:orientation="horizontal">
<View
android:id="@+id/dot_0"
android:layout_width="5dip"
android:layout_height="5dip"
android:layout_marginLeft="2dip"
android:layout_marginRight="2dip"
android:background="@drawable/dot_focused"/>
<View
android:id="@+id/dot_1"
android:layout_width="5dip"
android:layout_height="5dip"
android:layout_marginLeft="2dip"
android:layout_marginRight="2dip"
android:background="@drawable/dot_normal"/>
<View
android:id="@+id/dot_2"
android:layout_width="5dip"
android:layout_height="5dip"
android:layout_marginLeft="2dip"
android:layout_marginRight="2dip"
android:background="@drawable/dot_normal"/>
<View
android:id="@+id/dot_3"
android:layout_width="5dip"
android:layout_height="5dip"
android:layout_marginLeft="2dip"
android:layout_marginRight="2dip"
android:background="@drawable/dot_normal"/>
<View
android:id="@+id/dot_4"
android:layout_width="5dip"
android:layout_height="5dip"
android:layout_marginLeft="2dip"
android:layout_marginRight="2dip"
android:background="@drawable/dot_normal"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>
二、实现翻页事件
首先创建ViewPager适配器,其中getCount()用于返回要滑动的VIew的个数,destroyItem()从当前容器中删除指定位置(position)的View,instantiateItem()用来将当前视图添加到container中并返回当前View,isViewFromObject()不用管,按照官方提示来重写即可。
// 自定义Adapter
private class ViewPagerAdapter extends PagerAdapter {
//返回页卡的数量
@Override
public int getCount() {
return images.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup view, int position, Object object) {
// TODO Auto-generated method stub
view.removeView(images.get(position)) ;//删除页卡
}
//这个方法用来实例化页卡
@Override
public Object instantiateItem(ViewGroup view, int position) {
// TODO Auto-generated method stub
//添加图片控件到轮播图控件
view.addView(images.get(position));
return images.get(position);
}
创建图片点击事件
//图片点击事件
private class pagerImageOnClick implements View.OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.pager_image1:
Toast.makeText(MainActivity.this, "图片1被点击", Toast.LENGTH_SHORT).show();
break;
case R.id.pager_image2:
Toast.makeText(MainActivity.this, "图片2被点击", Toast.LENGTH_SHORT).show();
break;
case R.id.pager_image3:
Toast.makeText(MainActivity.this, "图片3被点击", Toast.LENGTH_SHORT).show();
break;
case R.id.pager_image4:
Toast.makeText(MainActivity.this, "图片4被点击", Toast.LENGTH_SHORT).show();
break;
case R.id.pager_image5:
Toast.makeText(MainActivity.this, "图片5被点击", Toast.LENGTH_SHORT).show();
break;
}
}
}
设置ViewPager
fl = (FrameLayout)findViewById(R.id.fl);
//获取屏幕宽高
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
// 屏幕宽度(像素)
int width = metric.widthPixels;
//设置布局容器宽度
fl.getLayoutParams().width=width;
//设置布局容器的高度
fl.getLayoutParams().height=width/2;
//声明轮播图控件
mViewPaper = (ViewPager) findViewById(R.id.vp);
//初始化显示的图片
images = new ArrayList<ImageView>();
//添加图片到图片集合
for (int i = 0; i < imageDrawables.length; i++) {
//初始化控件
ImageView imageView = new ImageView(this);
//设置图片背景
imageView.setBackgroundResource(imageDrawables[i]);
imageView.setId(imageIds[i]);
//设置点击事件
imageView.setOnClickListener(new pagerImageOnClick());
//图片添加到集合
images.add(imageView);
}
//初始化轮播图文字
title = (TextView) findViewById(R.id.title);
//设置轮播图显示文字
title.setText(titles[0]);
//小点集合
dots = new ArrayList<View>();
//初始化小点添加到集合
dots.add(findViewById(R.id.dot_0));
dots.add(findViewById(R.id.dot_1));
dots.add(findViewById(R.id.dot_2));
dots.add(findViewById(R.id.dot_3));
dots.add(findViewById(R.id.dot_4));
//初始化适配器
adapter = new ViewPagerAdapter();
//轮播图绑定适配器
mViewPaper.setAdapter(adapter);
//轮播图滑动事件监听
mViewPaper.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
//页面切换后触发
@Override
public void onPageSelected(int position) {
//设置轮播图文字
title.setText(titles[position]);
//设置当前小点图片
dots.get(position).setBackgroundResource(R.drawable.dot_focused);
//设置前一个小点图片
dots.get(oldPosition).setBackgroundResource(R.drawable.dot_normal);
//记录小点id
oldPosition = position;
//记录当前位置
currentItem = position;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
三、实现动画轮播自动翻页
利用线程池定时执行动画轮播,在活动开始时即开始定时任务实现自动每隔2s翻页
/**
* 利用线程池定时执行动画轮播
*/
ScheduledFuture beeperHandle;
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
//初始化定时线程
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
// 设定执行线程计划,初始2s延迟,每次任务完成后延迟2s再执行一次任务
beeperHandle=scheduledExecutorService.scheduleWithFixedDelay(
new ViewPageTask(),
2,
2,
TimeUnit.SECONDS);
}
private class ViewPageTask implements Runnable {
@Override
public void run() {
currentItem = (currentItem + 1) % imageIds.length;
//发送消息
mHandler.sendEmptyMessage(0);
}
}
/**
* 接收子线程传递过来的数据
*/
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
mViewPaper.setCurrentItem(currentItem);
};
};
到这里就可以实现轮播图的手动滑动、点击、动画轮播了,但是还有一个要注意的问题,在活动结束或者置于后台时应该停止此定时任务,否则将app置于后台再点击进去后,轮播的速度会变快很多,因为按照活动的生命周期,启动活动时调用oncreate方法再调用onstart()方法,每进入一次,就会新建一个轮播动画的任务,再加上以前进入时的定时任务还没有终止,任务叠加的越多轮播的速度就会快。所以我们可以利用生命周期重写onPause方法,在onPause()中新建一个线程来取消任务。
Override
protected void onPause() {
super.onPause();
// currentItem=0;
new Thread(new Runnable() {
public void run() {
//取消任务
beeperHandle.cancel(true);
}
}).start();
}
效果如下:
完整代码已经上传到码云了点击查看 如果有帮助的话请点一个star呀,笔芯❤