我们在停车场或公交车站有时候会看到LCD屏上面有滚动的广告,他们一般是通过安卓系统实现的。原理就是通过网络接口,或本地查询图片文件又或者直接调用app里的资源文件,通过viewpager加载imagerview,在通过scheduledExecutorService定时器循环播放图片。代码如下:
private View view;
private ViewPager vp;
private int[] pics = {R.drawable.img1, R.drawable.img2, R.drawable.img3,
R.drawable.img4};//图片集合
private ImageView[] dots;//点的集合
private List<ImageView> list;
private int imgsize;// 整个适配器的总长
private ScheduledExecutorService scheduledExecutorService;// 定时周期执行指定任务
private int currentIndex;// (自动播放时)定时周期要显示的图片的索引(viewpager中的图片位置)
private int dotIndex = 1;// 设置当前点的索引
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragmentimage, container, false);
initView();
return view;
}
private void initView() {
vp = (ViewPager) view.findViewById(R.id.fraImaVp);
initDot();
initViewpage();
}
/*初始化下面的点*/
private void initDot() {
LinearLayout ll = (LinearLayout) view.findViewById(R.id.fraImall);
dots = new ImageView[pics.length];
for (int i = 0; i < pics.length; i++) {
//动态添加滚轮下面的小点
dots[i] = new ImageView(getActivity());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
int distance = 9;
params.setMargins(distance, distance, distance, distance);
dots[i].setLayoutParams(params);
dots[i].setImageResource(R.drawable.dot_bg);
ll.addView(dots[i]);
}
dots[0].setPressed(true);
}
/**
* viewpager初始化
*/
private void initViewpage() {
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleWithFixedDelay(new ViewPagerTask(), 6,
6, TimeUnit.SECONDS);// 自动播放
vp.addOnPageChangeListener(pageChangeListener);
list = new ArrayList<>();
for (int i = 0; i < pics.length + 2; i++) {
ImageView imageView = new ImageView(getActivity());
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
list.add(imageView);
}
setImgRes(pics.length + 2);
}
private void setImgRes(int length) {
imgsize = length;
list.get(0).setImageResource(pics[pics.length-1]);
list.get(length-1).setImageResource(pics[pics.length-1]);
for (int i = 0; i < length - 2; i++) {
list.get(i + 1).setImageResource(pics[i]);
}
/*默认选中物理第二张图片*/
vp.setAdapter(new ImageViewAdapter(list));
vp.setCurrentItem(1);
}
ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (positionOffset == 0.0) {
if (position == 0) {
vp.setCurrentItem(imgsize - 2, false);
} else if (position == imgsize - 1) {
vp.setCurrentItem(1, false);
}
}
}
@Override
public void onPageSelected(int position) {
currentIndex = position;// 把当前页的索引记住,方便跳转到下一页(这是必须的)
if (currentIndex!=imgsize-1&¤tIndex!=0) {
Logs.d("aaaa "+currentIndex);
setCurrentDot(currentIndex);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
};
/**
* 设置当前点的颜色
*/
private void setCurrentDot(int currentIndex) {
dots[currentIndex - 1].setPressed(true);
dots[dotIndex].setPressed(false);
dotIndex = currentIndex - 1;
}
/**
* 来定时播放图片的线程
*/
private class ViewPagerTask implements Runnable {
@Override
public void run() {
currentIndex++;
handler.obtainMessage().sendToTarget();
}
}
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
// 使viewpager跳转到指定页(true:带有滑动效果)
vp.setCurrentItem(currentIndex, true);
}
};
解析:
SetImageView方法:
* 除去第一个和最后一个imageview,其他的imageview依次设置相应的图片,顺序与imgs里的一样 * 最后再把第一个imageview的图片设置为imgs中的最后一张图片 * ,把最后一个imageview的图片设置为imgs中的第一张图片(因为向做滑动到第一张时 * ,再向左滑动就到了最后一张;向右滑动一样,到了最后一张,再向右滑动就到了第一张) * 比如:要显示的图片为: A B C D四张图片,此时我们要把它们构造成: D {A B C D}A * 中间大括号里的就是要显示的图片,第一个D和最后一个A就是滑动到头时继续再滑动时逻辑上要展示的图片
OnepageListerner监听者:
/** * 监听viewpager的滑动过程,可获取滑动的百分比(arg1)参数。 * 这里判断的方法是:当滑动到第索引为0的那一页时(即:在逻辑上是到了第一张图片,此时viewpager会显示索引为0的那张图片 * (即在视觉效果上是最后一张的图片,因为,第一张过了再向左滑动,就是最后一张 * )。如果再这里不做相应的处理,再向左滑动就滑不动了,因为已经到了viewpager的第一张 * (索引为0),此时我们就要依靠参数arg1的值来判断是否已经完成了滑动到第一张 * ,当arg1的值为0.0时,即已经滑动完成,此时我们就把viewpager的页面跳转到viewpager的倒数第二张页面上 * ,使用setcurrentItem D{A B C D}A * (Int,boolean)方法,当Boolean取值为FALSE时,就没有滑动效果,直接跳转过去,由于当前页的图片和要跳转到的页面一样 * ,所以在视觉效果上看不出闪烁 ,这样就很自然的跳转到了倒数第二张,然后继续向左滑动 */主要布局很简单就是一个viewpager和包装点的LinearLayout.
<android.support.v4.view.ViewPager
android:id="@+id/fraImaVp"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:id="@+id/fraImall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="177dp"
android:orientation="horizontal">
</LinearLayout>
滚轮点的背景R.drawable.dot_bg
其实就是两张图片
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/dot_press" android:state_focused="true"/>
<item android:drawable="@drawable/dot_press" android:state_pressed="true"/>
<item android:drawable="@drawable/dot"/>
</selector>
效果图