实现思路就是通过viewPager自定义组件,支持图片点击、手动滑动、自动轮播、初始化定位位置。不废话了先上图



组件下载

组件使用

public class BannerAutoActivity extends Activity {    BannerLayout bannerLayout;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_banner_auto);        initView();    }    private void initView(){        //界面初始化view        bannerLayout = (BannerLayout) findViewById(R.id.bannerLayout);        //组织界面图片数据        List ivList = new ArrayList<>();        for(int i=0;i<6;i++){            ImageView imageView = new ImageView(this);            ViewGroup.LayoutParams layoutParams = new LinearLayout.LayoutParams(                    LinearLayout.LayoutParams.FILL_PARENT,                    LinearLayout.LayoutParams.FILL_PARENT);            imageView.setLayoutParams(layoutParams);            imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);            imageView.setImageResource(R.mipmap.banner_01+i);            ivList.add(imageView);        }        //设置初始展示第几张//        bannerLayout.setIdx(0);        bannerLayout.startBanner(ivList,R.drawable.point_background);        //图片点击事件监听        bannerLayout.setonClickImg(new BannerLayout.onClickImg() {            @Override            public void ItemId(int id) {                int temp = id+1;                Toast.makeText(BannerAutoActivity.this,"这是第"+temp+"张图",Toast.LENGTH_SHORT).show();            }        });    }}
到此通过组件就可以实现上图的效果了。继续向下看,自定义view内部的内容。
自定义View一共用了三个文件。
Banners.java
    
ChildViewPager.java
    
BannerLayout.java

实体类

Banners.java

public class Banners {private String picurl;private String url;private String name;public void setPicurl(String picurl) {this.picurl = picurl;}public String getPicurl() {return this.picurl;}public void setUrl(String url) {this.url = url;}public String getUrl() {return this.url;}public void setName(String name) {this.name = name;}public String getName() {return this.name;}}

自定义viewPager

ChildViewPager.java

主要重写 onTouchEvent(),实现点击监听和解决滑动冲突问题。因为在项目中当前界面为ScrollView,所以有滑动冲突问题。
    @Override      public boolean onTouchEvent(MotionEvent arg0) {          // TODO Auto-generated method stub          //每次进行onTouch事件都记录当前的按下的坐标          curP.x = arg0.getX();          curP.y = arg0.getY();            if(arg0.getAction() == MotionEvent.ACTION_DOWN){              //记录按下时候的坐标              //切记不可用 downP = curP ,这样在改变curP的时候,downP也会改变              downP.x = arg0.getX();              downP.y = arg0.getY();              //此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰              getParent().requestDisallowInterceptTouchEvent(true);          }            if(arg0.getAction() == MotionEvent.ACTION_MOVE){              //此句代码是为了通知他的父ViewPager现在进行的是本控件的操作,不要对我的操作进行干扰              getParent().requestDisallowInterceptTouchEvent(true);          }            if(arg0.getAction() == MotionEvent.ACTION_UP){              //在up时判断是否按下和松手的坐标为一个点  这里可以把判断放松一点            //如果是一个点,将执行点击事件,这是我自己写的点击事件,而不是onclick              if(downP.x==curP.x && downP.y==curP.y){                  onSingleTouch();                  return true;              }  //         return super.onTouchEvent(arg0);          }            return super.onTouchEvent(arg0);      }            /**      * 单击      */      public void onSingleTouch() {          if (onSingleTouchListener!= null) {                onSingleTouchListener.onSingleTouch();          }      }  

重头戏来啦

BannerLayout.java

首先是初始化函数
    
 public BannerLayout(Context context, AttributeSet attrs) {        super(context, attrs);        this.context = context;        LayoutInflater.from(context).inflate(R.layout.viewpager_banner, this);        setUpView();    }    private void setUpView() {        mViewPager = (ChildViewPager) findViewById(R.id.viewpager);        llPoints = (LinearLayout) findViewById(R.id.ll_points);        mViewPager.setOnSingleTouchListener(new ChildViewPager.OnSingleTouchListener() {            @Override            public void onSingleTouch() {                // TODO Auto-generated method stub                onClickImg.ItemId(currentId%ivList.size());            }        });        ivList = new ArrayList<>();        llPoints.removeAllViews();    }


这里就能看到使用中的影子了,设置数据
 /**     * @param dotId  圆点资源id     * @param ivList 参数的size必需相等,不然报错     */    public void startBanner(List ivList, int dotId) {        this.ivList = ivList;        for (int i = 0; i < ivList.size(); i++) {            view = new View(context);            view.setBackgroundDrawable(getResources()                    .getDrawable(dotId));            initPoint(view, pointSmall);            view.setEnabled(false);            llPoints.addView(view);        }        initDataImg();    }    /**     * 设置数据     */    private void initDataImg() {        ViewPagerAdapter adapter = new ViewPagerAdapter();        mViewPager.setAdapter(adapter);        mViewPager.setOnPageChangeListener(this);        llPoints.getChildAt(0).setEnabled(true);        initPoint(llPoints.getChildAt(0), pointBig);        mViewPager.setCurrentItem(idx);        imgHandler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);    }

这些都是viewPager的惯用方法。下边说说自动轮播的实现。 自动轮播通过handle队列机制呼叫实现,handle设置如下
    /**     * 请求更新显示的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 long MSG_DELAY = 3000;    private Handler imgHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            // TODO Auto-generated method stub            super.handleMessage(msg);            // 检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。            if (imgHandler.hasMessages(MSG_UPDATE_IMAGE)) {                imgHandler.removeMessages(MSG_UPDATE_IMAGE);            }            switch (msg.what) {                case MSG_UPDATE_IMAGE:                    mViewPager.setCurrentItem(currentId + 1);                    // 准备下次播放                    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:                    // 记录当前的页号,避免播放的时候页面显示不正确。                    // currentIcon = msg.arg1;                    break;                default:                    break;            }        }    };

在viewPage r的监听器onPageScrollStateChanged中我们 以使用handle中的方法达到想要的效果
    @Override    public void onPageScrollStateChanged(int arg0) {        // Auto-generated method stub        switch (arg0) {            case ViewPager.SCROLL_STATE_DRAGGING:                imgHandler.sendEmptyMessage(MSG_KEEP_SILENT);                break;            case ViewPager.SCROLL_STATE_IDLE:                imgHandler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);                break;            default:                break;        }    }    @Override    public void onPageScrolled(int arg0, float arg1, int arg2) {        // Auto-generated method stub    }    @Override    public void onPageSelected(int position) {        // 切换选中的点        llPoints.getChildAt(previousSelectPosition).setEnabled(false); // 把前一个点置为normal状态        initPoint(llPoints.getChildAt(previousSelectPosition), pointSmall);        llPoints.getChildAt(position % ivList.size()).setEnabled(true); // 把当前选中的position对应的点置为enabled状态        initPoint(llPoints.getChildAt(position % ivList.size()), pointBig);        previousSelectPosition = position % ivList.size();        currentId = position;        imgHandler.sendMessage(Message.obtain(imgHandler, MSG_PAGE_CHANGED,                position, 0));    }

组件下载

更多相关文章

  1. Fresco对Eclipse的支持以及使用教程
  2. Android启动流程简析(三)
  3. Android一些开源第三方
  4. 常用的Android(安卓)Widget组件学习②-EditText的介绍和应用。
  5. android中使用多个CheckBox联动,CheckBox的setOnCheckedChangeLis
  6. Android通过PendingIntent实现消息通知
  7. Android(安卓)SparseArray的用法
  8. Android(安卓)源码环境搭建配置与问题解析(二)
  9. Bmob SDK导入和初始化

随机推荐

  1. [Android]代码实现StateListDrawable
  2. android - 头中尾布局
  3. android baidupush
  4. Android中添加水平线
  5. Android graphics画图的点击事件处理
  6. Android中Acition和Category常量表
  7. Android Studio 无法启动虚拟机的问题
  8. android 混淆手册
  9. Android(安卓)- webview通过js调用Androi
  10. Android_android studio使用 9patch常见