我们常用的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>
ViewPager的具体操作,比如初始化ViewPager,然后setAdapter这些就不说了。只要会使用ViewPager,需求1就做完了,不过为了讲下一点内容,我这里还是复制代码吧,
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显示的数据的条数,这种情况下,当你已经右滑到最后一张的时候,就不能再右滑动,左滑动到第一张的时候,就不能再向左滑动了。

      我们生活中,更多的是让用户可以循环滑动,向右边滑动到最后一张的时候,如果还右滑,就显示第一张,也就是可以无限的左右滑动,左滑类似,滑动到第一张还滑动的话,就显示最后一张,然后一直循环。
      这种情况下,我第一想到的是监听ViewPager的滑动,结果它里面的方法不止调用一次,不好控制,最后参考网友的做法,主要在Adapter去控制
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开始的。参考

       为了让ViewPager右下角的圆点跟上ViewPager(也就是需求5),我们需要监听ViewPager,代码如下:
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) {
         }});
当ViewPager要实现循环,我们要注意,使用position的地方都要:positon=position%views.size();
需求6:初始化RadioGroup,在监听RadioGroup的时候,去判断是哪个RadioButton,从而控制ViewPager显示那一张广告图 viewpager.setCurrentItem(x)
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
    }
}
需求2,自动播放广告栏

(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制作广告栏相关推荐

  1. 【Android 应用开发】Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题

    . 参考界面 : 携程app首页的广告栏, 使用ViewPager实现        自制页面效果图 : 源码下载地址: http://download.csdn.net/detail/han1202 ...

  2. android ViewPager轮播制作成品——轮播制作(六)

    android ViewPager轮播制作成品--轮播制作(六) 本文主要参考文章:Android 使用ViewPager实现左右循环滑动图片 下面整体介绍一下本系列文章.目的是想要做一个广告.通知轮 ...

  3. android viewpager 嵌套fragment,Android ViewPager+Fragment多层嵌套(使用问题处理)

    之前写了Android ViewPager+Fragment(使用问题处理),封装了一个BaseFragment,对于简单使用ViewPager+Fragment而言,是没有问题的. 不过,ViewP ...

  4. Android -- ViewPager切换动画,PageTransformer

    transformPage(View view, float position) view就是滑动中的那个view,position这里是float类型,是当前滑动状态的一个表示,比如当滑动到正全屏时 ...

  5. android开发实例之viewpager无限循环+自动滚动,Android ViewPager实现无限循环的实例...

    Android ViewPager实现无限循环的实例 ViewPager自身并不支持左右无限循环的功能,这里就提供一种方案让Android ViewPager实现左右无限循环的功能,这里记录下: 用于 ...

  6. 怎么用Android做登录界面,利用Android怎么制作一个APP登录界面

    利用Android怎么制作一个APP登录界面 发布时间:2020-12-02 17:09:10 来源:亿速云 阅读:79 作者:Leah 这期内容当中小编将会给大家带来有关利用Android怎么制作一 ...

  7. android viewpager动态加载页面,Android viewpager中动态添加view并实现伪无限循环的方法...

    本文实例讲述了Android viewpager中动态添加view并实现伪无限循环的方法.分享给大家供大家参考,具体如下: viewpager的使用,大家都熟悉,它可以实现页面之间左右滑动的切换,这里 ...

  8. android ViewPager 实现点击小圆点切换页面 案例

    android ViewPager  实现点击小圆点切换页面 说明:在viewpager中,通过左右滑动可以切换页面,同样可以通过点击所指示的小圆点来滑动到某个页面页面. 具体实现方法如下: 主要ac ...

  9. Android ViewPager 重复数据问题的解决方法

    Android ViewPager 重复数据问题的解决方法 参考文章: (1)Android ViewPager 重复数据问题的解决方法 (2)https://www.cnblogs.com/Linc ...

最新文章

  1. cbow 和skip-gram比较
  2. Base64编码和解码
  3. cmd中运行python文件,并带参数
  4. C++ Primer Plus(十一)—— 使用类
  5. python3.7.2安装包_Win10下python 2.7与python 3.7双环境安装教程图解
  6. 江门农商银行引入阿里云AnalyticDB,实现数据自助分析平台升级
  7. 无线对讲调度服务器,无线对讲系统解决方案
  8. vb 获取系统声音的电平_质量好的背景音乐系统套装效果图
  9. .net 宏定义_C语言基础知识:几种特殊的函数宏封装方式
  10. java连接mysql表格_java中表格连接数据库
  11. input单选框多选框时可用的事件
  12. CentOS_5.5_安装GCC编译LiME
  13. Dais-CMX系列现代计算机组成原理,dais版本计算机组成原理实验指导.doc
  14. 国资入局,苏宁“零售服务商”升级战略获得最强助力
  15. 【密码专栏】动手计算双线性对(上)
  16. Xmodem、Ymodem和Zmodem协议是最常用的三种通信协议
  17. Excel Vba编程初探一
  18. MeasureSpec介绍
  19. ajax回调的data,。。。Ajax的回调函数function(data)中,data的返回类型。。。
  20. 组建团队--共同愿景

热门文章

  1. 视频编辑王(视频剪辑软件)
  2. grafana统计接口访问量
  3. python 时间戳转iso 8601_ISO8601时间字符串到时间戳处理
  4. 阿伏法机器人_深圳自动捷克钻不良QC机器人操作
  5. fir高通滤波器matlab程序,基于MATLAB的有限序列FIR高通滤波器源代码
  6. 数据存储——声音存储
  7. 大规模文件存储怎么办?10分钟学会阿里OSS对象存储
  8. 应届生校招Java学习经验
  9. 【Android Framework系列】第2章 Binder机制大全
  10. HTML5离线存储利与弊