android ViewPager制作广告栏
我们常用的app中,首页多半都会展示广告的地方(特别是电商产品),比如下面这张图中被圈出的部分,就是我所说的广告栏
广告栏的需求就是:展示活动的广告图,
(1)用户可以左右滑动来选择;
(2)广告可以自动轮流播放,即过一定时间,展示下一张广告;
(3)当用户手指触摸到广告栏时,自动播放停止
(5)图片右下角的圆点和广告图播放位置显示一致,即:播放第一种,第一个圆点亮,其他都暗
(6)圆点可以点击,即:点第三个圆点,展示第三张广告图
实现
看到需求1,首先想到控件ViewPager,看到需求6,想到的是右下角的圆点是RadioButton,这样很容易就控制了单选。先满足这两个要求的实现吧!
广告栏的布局:
main_activity.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="400dp" android:background="#696969" /> <include layout="@layout/radio_layout" /> </RelativeLayout>
radio_layout.xml就是单选按钮的布局:
<?xml version="1.0" encoding="utf-8"?> <RadioGroup xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/RadioGroup" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/viewpager" android:layout_alignParentRight="true" android:layout_marginBottom="5dp" android:orientation="horizontal"> <RadioButton android:id="@+id/radio1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:button="@null" android:checked="true" android:drawableLeft="@drawable/radiobutton_selector" android:padding="2dp" /> <RadioButton android:id="@+id/radio2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:button="@null" android:drawableLeft="@drawable/radiobutton_selector" android:padding="2dp" /> <RadioButton android:id="@+id/radio3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:button="@null" android:drawableLeft="@drawable/radiobutton_selector" android:padding="2dp" /> <RadioButton android:id="@+id/radio4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:button="@null" android:drawableLeft="@drawable/radiobutton_selector" android:padding="2dp" /> </RadioGroup>
public class ViewPagerAdapter extends PagerAdapter {//界面列表 private List<View> views; public ViewPagerAdapter (List<View> views){ this.views = views; } @Override public int getCount() { return views==null?0:views.size(); }@Override public void destroyItem(View container, int position, Object arg2) { ((ViewPager)container).removeView(views.get(position)); }@Override public Object instantiateItem(View container, int position) { ((ViewPager)container).addView(views.get(position), 0); return views.get(position); }@Override public boolean isViewFromObject(View arg0, Object arg1) { return (arg0 == arg1); }
@Override // public void destroyItem(ViewGroup container, int position, Object object) { // container.removeView((View) object); // } // // @Override // public Object instantiateItem(ViewGroup container, int position) { // /** // * 设置具体需要填充的View对象 // */ // int i = position % views.size(); // container.addView(views.get(i)); // return views.get(i); // }
}
ViewPager的初始化,和setAdapter代码:
views = new ArrayList<>(); LinearLayout.LayoutParams mParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); for (int i = 0; i < picPath.length; i++) {ImageView iv = new ImageView(this); iv.setLayoutParams(mParams); iv.setImageResource(pics[i]); iv.setScaleType(ScaleType.FIT_XY); views.add(iv); }vpAdapter = new ViewPagerAdapter(views); vp.setAdapter(vpAdapter);
上面这种情况就是我们一般使用的ViewPager,我们的list有多少数据就传过去多少数据,在Adapter的getCount()方法里面,list.size()来决定我们ViewPager显示的数据的条数,这种情况下,当你已经右滑到最后一张的时候,就不能再右滑动,左滑动到第一张的时候,就不能再向左滑动了。
public class ViewPagerAdapter extends PagerAdapter {//界面列表 private List<View> views; public ViewPagerAdapter (List<View> views){ this.views = views; } @Override public int getCount() { return Integer.MAX_VALUE; //设置成最大,使用户看不到边界 // return views==null?0:views.size(); }@Override public void destroyItem(View container, int position, Object arg2) {((ViewPager)container).removeView(views.get(position % views.size())); // ((ViewPager)container).removeView(views.get(position)); }@Override public Object instantiateItem(View container, int position) {((ViewPager)container).addView(views.get(position % views.size()), 0); return views.get(position % views.size()); // ((ViewPager)container).addView(views.get(position), 0); // return views.get(position); }@Override public boolean isViewFromObject(View arg0, Object arg1) { return (arg0 == arg1); } }
上面的代码中,注释的地方就是不循环的代码,注意:我们在getCount()里面给的是最大的条数,这样保证ViewPager可以一直左滑动右滑动,让数据循环显示重点在views.get(position%views.size())这句代码上,给用户的感觉就是在循环显示,其实呢,不是循环,你打印position就知道,它一直在递增,我们只是让views.get()出来的数据是循环的(views.get出来的数据:1,2,3,......list.size(),1,2,3.....list.size()这样实现循环的)。而要实现一开始就可以左滑动,网友的办法是vp.setCurrentItem(views.size()*10);这样只是一个障眼法,让用户看到的第一张position就不是0开始的。参考
vp.setOnPageChangeListener(new OnPageChangeListener() {@Override public void onPageSelected(int position) {position=position%views.size();//循环时,一定要有这句,不然会越界异常 radioButton = (RadioButton) group.getChildAt(position); radioButton.setChecked(true); }@Override public void onPageScrolled(int positon, float arg1, int arg2) { }@Override public void onPageScrollStateChanged(int state) { }});
RadioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {@Override public void onCheckedChanged(RadioGroup group, int checkId) {switch (checkId) {case R.id.radio1:vp.setCurrentItem(0); break; case R.id.radio2:vp.setCurrentItem(1); break; case R.id.radio3:vp.setCurrentItem(2); break; case R.id.radio4:vp.setCurrentItem(3); break; default:break; }}}); }
一般情况下,网页版的会考虑上面的需求(6),手机端很少有app会这样做,可能是手机页面本身就小,圆点就更小了,让用户可点的话,用户很容易就会点击到广告图,所以这种效果不佳。所以我们去掉需求6,那么圆点就是图片实现,每次ViewPager显示的图片改变的时候,都要调用下面的setCurPage(intpage, intcount)方法,去改变圆点的显示效果,page是当前页,count是广告图片数量,这样还有一个好处就是,可以根据接口获得的广告图片数量,来决定圆点的数量,比直接在布局中写死灵活很多。
这样广告栏的布局变成:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="400dp" android:background="#696969" /> <LinearLayout android:id="@+id/three_tv_viewpager_dot1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerInParent="true" android:orientation="horizontal" android:layout_marginBottom="12dp"/> </RelativeLayout>
里面的LinearLayout是用来装圆点的
LinearLayout dot = (LinearLayout) view.findViewById(R.id.three_tv_viewpager_dot1);
public void setCurPage(int page, int count) {try {dot.removeAllViews(); for (int i = 0; i < count; i++) {ImageView imgCur = new ImageView(getActivity()); imgCur.setBackgroundResource(R.drawable.news_dot1); imgCur.setId(i); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(-2, -2); lp.rightMargin = 5; if (imgCur.getId() == page) {imgCur.setBackgroundResource(R.drawable.news_dot); }dot.addView(imgCur, lp); }} catch (Exception e) {// TODO: handle exception } }
(1)定义一个全局变量:private int currentItem; // 当前页面
(这是为了记录当前页面,这样自动播放的时候才会知道该显示哪一页,所以单选按钮切换的时候viewpager.setCurrentItem(x);更改当前页面的currentItem 值:currentItem = x,滑动改变页面的时候也要写:currentItem = position;)
(2)自动滚动肯定要开线程,线程做的就是停一点时间(比如2秒),完了之后告诉Hanlder去改变显示的页面:
private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {// 设置当前页面 vp.setCurrentItem(currentItem); }; };
(3)在onStart()里面开启ScheduledExecutorService,再onPause()里面关闭ScheduledExecutorService
private ScheduledExecutorService scheduledExecutorService; @Override protected void onStart() {super.onStart(); scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); // 每隔2秒钟切换一张图片 scheduledExecutorService.scheduleWithFixedDelay(new ViewPagerTask(), 2, 2, TimeUnit.SECONDS); // scheduleAtFixedRate(command, initialDelay, period, unit); // command:执行线程 initialDelay:初始化延时 period:前一次执行结束到下一次执行开始的间隔时间(间隔执行延迟时间) // unit:计时单位 } @Override protected void onStop() {if (scheduledExecutorService!=null){scheduledExecutorService.shutdown(); }super.onStop(); } // 切换图片 private class ViewPagerTask implements Runnable {@Override public void run() {currentItem = (currentItem + 1) % pics.length; // 更新界面 handler.obtainMessage().sendToTarget(); // message对象sendToTarget(),handler对象sendMessage(); } }
这就能实现图片像广告一样自动播放,也可以滑动选择。
实现暂停一段时间再显示,这个功能有很多方法,上面讲到的ScheduledExecutorService可以,Timer计时器也可以,或者直接用handler设置延迟时间有可以做到。
private int currentItem=0; // 当前页面 /** * 焦点图自动滚动方法 * * @param delayTimeInMills */ private final int SCROLL_WHAT = 1; private boolean mIsStop = false;// 焦点图触摸暂停监听 private Handler handler = new Handler() {@Override public void handleMessage(Message msg) {super.handleMessage(msg); switch (msg.what) {case SCROLL_WHAT:if (currentItem == views.size()) {currentItem = 0; }//点击图片时,自动切换暂停 if (!mIsStop) {currentItem++; vp.setCurrentItem(currentItem % views.size()); }sendScrollMessage(4000); break; }} }; private void sendScrollMessage(long delayTimeInMills) {/** remove messages before, keeps one message is running at most **/ handler.removeMessages(SCROLL_WHAT); handler.sendEmptyMessageDelayed(SCROLL_WHAT, delayTimeInMills); }
setAdapter之后就开启自动切换,
vp.setAdapter(vpAdapter); vp.setCurrentItem(0);// 默认显示第一张 sendScrollMessage(300);// 自动切换启动
ViewPager触摸监听,实现触摸的时候,暂停自动切换,即功能3
//ViewPager 触摸事件 vp.setOnTouchListener(new View.OnTouchListener() {@Override public boolean onTouch(View arg0, MotionEvent event) {int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN) {mIsStop = true; } else if (action == MotionEvent.ACTION_UP) {mIsStop = false; }return false; } });
目前:手动循环滑动加上自动播放共同的效果,会出现异常,有待解决
左右滑动,不支持循环滑动,自动播放,可以点击右下角切换ViewPager显示图的:
源代码:http://download.csdn.net/detail/qq_30716173/9273873
android ViewPager制作广告栏相关推荐
- 【Android 应用开发】Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题
. 参考界面 : 携程app首页的广告栏, 使用ViewPager实现 自制页面效果图 : 源码下载地址: http://download.csdn.net/detail/han1202 ...
- android ViewPager轮播制作成品——轮播制作(六)
android ViewPager轮播制作成品--轮播制作(六) 本文主要参考文章:Android 使用ViewPager实现左右循环滑动图片 下面整体介绍一下本系列文章.目的是想要做一个广告.通知轮 ...
- android viewpager 嵌套fragment,Android ViewPager+Fragment多层嵌套(使用问题处理)
之前写了Android ViewPager+Fragment(使用问题处理),封装了一个BaseFragment,对于简单使用ViewPager+Fragment而言,是没有问题的. 不过,ViewP ...
- Android -- ViewPager切换动画,PageTransformer
transformPage(View view, float position) view就是滑动中的那个view,position这里是float类型,是当前滑动状态的一个表示,比如当滑动到正全屏时 ...
- android开发实例之viewpager无限循环+自动滚动,Android ViewPager实现无限循环的实例...
Android ViewPager实现无限循环的实例 ViewPager自身并不支持左右无限循环的功能,这里就提供一种方案让Android ViewPager实现左右无限循环的功能,这里记录下: 用于 ...
- 怎么用Android做登录界面,利用Android怎么制作一个APP登录界面
利用Android怎么制作一个APP登录界面 发布时间:2020-12-02 17:09:10 来源:亿速云 阅读:79 作者:Leah 这期内容当中小编将会给大家带来有关利用Android怎么制作一 ...
- android viewpager动态加载页面,Android viewpager中动态添加view并实现伪无限循环的方法...
本文实例讲述了Android viewpager中动态添加view并实现伪无限循环的方法.分享给大家供大家参考,具体如下: viewpager的使用,大家都熟悉,它可以实现页面之间左右滑动的切换,这里 ...
- android ViewPager 实现点击小圆点切换页面 案例
android ViewPager 实现点击小圆点切换页面 说明:在viewpager中,通过左右滑动可以切换页面,同样可以通过点击所指示的小圆点来滑动到某个页面页面. 具体实现方法如下: 主要ac ...
- Android ViewPager 重复数据问题的解决方法
Android ViewPager 重复数据问题的解决方法 参考文章: (1)Android ViewPager 重复数据问题的解决方法 (2)https://www.cnblogs.com/Linc ...
最新文章
- cbow 和skip-gram比较
- Base64编码和解码
- cmd中运行python文件,并带参数
- C++ Primer Plus(十一)—— 使用类
- python3.7.2安装包_Win10下python 2.7与python 3.7双环境安装教程图解
- 江门农商银行引入阿里云AnalyticDB,实现数据自助分析平台升级
- 无线对讲调度服务器,无线对讲系统解决方案
- vb 获取系统声音的电平_质量好的背景音乐系统套装效果图
- .net 宏定义_C语言基础知识:几种特殊的函数宏封装方式
- java连接mysql表格_java中表格连接数据库
- input单选框多选框时可用的事件
- CentOS_5.5_安装GCC编译LiME
- Dais-CMX系列现代计算机组成原理,dais版本计算机组成原理实验指导.doc
- 国资入局,苏宁“零售服务商”升级战略获得最强助力
- 【密码专栏】动手计算双线性对(上)
- Xmodem、Ymodem和Zmodem协议是最常用的三种通信协议
- Excel Vba编程初探一
- MeasureSpec介绍
- ajax回调的data,。。。Ajax的回调函数function(data)中,data的返回类型。。。
- 组建团队--共同愿景