给予 HorizontalListView 自定义banner

首先上图
这里写图片描述

eg:

类似传统的banner,唯一不同点在ui展示。前一张,后一张需要显示一点。每次滚动一张。手指放上暂停滚动,放开开始滚动。

实现思路:
Horizontal Listview 中已经实现基本的view 左右滚动,需要理解几个系统API,Scroller ,GestureDetector,Timer,View 绘制流程,事件分发机制

代码事例

这里写图片描述

设置两个view 之间的间距,测量banner单张view的宽度。因为需要用view 宽度来计算,滚动距离

这里写图片描述

这里写图片描述

            计算公式: (屏幕宽度-单张view)/2 =  默认偏移量

horizontalListview 绘制开始,将偏移量传给view 进行绘制。展示默认中间位置,开始滚动

这里写图片描述

在 GestureDetector的onfling()中进行左右滑动判断。进行控制每次只滑动一个view的距离。

注意:
这里需要消耗 事件所以返回 true。否则,滑动会有卡顿现象。

开启线程进行滚动逻辑

 private Runnable mImageTimerTask = new Runnable() {
        @Override
        public void run() {
            int mMultiple = ++IncrementTimer;
            //fling to center position
            if (IncrementTimer == 1) {
                scrollTo(mVieWidth);
            } else {
                int customRuler = (mVieWidth * mMultiple);
                int mScroller = HorizontalListView.this.mScroller.getCurrX() - mVieWidth;

                if (isClockWise) { //顺时针
                    scroRight2Left(customRuler, mScroller);
                } else {
                    scroLeft2Right(customRuler, mScroller);
                }

            }
            if (isFirstRuning) {
                mTimerHandler.postDelayed(mImageTimerTask, 3000);
            } else {
                mTimerHandler.postDelayed(mImageTimerTask, 5000);
            }
            isFirstRuning = false;
        }
};

设置一个自增变量。每次执行进行 mVieWidth * mMultiple 滚动距离计算,可以根据 类里面提供的mNextX来计算下次需要滚动的距离。

在这里去掉了 DataSetObserver 监听重绘事件,如果加上会引起右边显示空白问题。

计算的核心方式:

        removeNonVisibleItems(dx); 一处不可见的view

        fillList(dx); //填充左右view

        positionItems(dx); 计算偏移量

最近发现第一版有些问题需要优化。嵌套scrollview 时候 不容易滑动,会出现偶发的滚动乱序问题。现将2版优化思路写出来!

1.前一个版本使用 手势事件进行处理。onFling()中处理,当滑动条件达不到不触发 onFling(),优化点就是,在onscroll() 处理滑动事件。onscroll()每次均会被触法多次。

 if (mScroller.isFinished() && !mIsAutoScrolling) {
                controlOnFling(e1, e2);
                return true;
            }

上面就是,优化点。当scroller 滚动停止的时候,去调用滚动事件。scrollTo()

   /**
         * 自己处理fling
         * @param e1
         * @param e2
         */
        private void controlOnFling(MotionEvent e1, MotionEvent e2) {
            int horizontalMinDistance = 20;
            mIsFingerSlide = true;
            if (e1.getX() - e2.getX() > horizontalMinDistance) {
                scrollTo(mScroller.getCurrX() + mVieWidth);
            } else if (e2.getX() - e1.getX() > horizontalMinDistance) {
                scrollTo(mScroller.getCurrX() - mVieWidth);
            }
        }

优化过的代码,稍后贴出来;

更新 2015/5/11

最近发现一种更好的实现方式 改变一个属性。就可以吧 viewpager banner 修改成效果图的样式

http://blog.csdn.net/lmj623565791/article/details/51339751 j

demo 链接:http://pan.baidu.com/s/1pK7FMdX

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

灯塔@kuaidao

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

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

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

打赏作者

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

抵扣说明:

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

余额充值