android 图片轮播(自动循环轮播)

实现思路就是通过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<ImageView> 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<ImageView> 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));
    }

组件下载

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风晴03

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值