自定义 弧形滑动条 CricleScrollView

1.最进要做一个需求==>将listView  与 CricleScrollView关联  ,根据ListView 的滑动来控制CricleScrollView滑动块的位置  CricleScrollView,类似moto ticWatch主界面的 弧形ScrollView.网上关于弧形ScrollView, 网上的资源可以说少之又少.   其实View的绘制并不难,难点在于如何实时的调整
摘要由CSDN通过智能技术生成
1.最进要做一个需求==>将listView  与 CricleScrollView关联  ,根据ListView 的滑动来控制CricleScrollView滑动块的位置CricleScrollView,类似moto ticWatch主界面的 弧形ScrollView.网上关于弧形ScrollView, 网上的资源可以说少之又少. 其实View的绘制并不难,难点在于如何实时的调整滑动块的位置.


2.CricleScrollView 为了不影响ListView的触摸事件, 需要直接继承View,利用 View的onMeasure()  和 onDraw()方法来完成,利用canvas.drawArc通过两个Paint对象 分别画出滑动条的滑动背景(范围) 和 滑动条


3.那么问题来了,如何去确认背景弧长,活动条弧长呢?其实估计大家都能想到drawArc方法可以通过传入起始角度和活动距离,分别来画出背景和滑动条的长度.


4.那么问题又来了,如何去让CricleScrollView滑动块的位置与listview 的上下拉同步了.刚开始我是想通过滑动总的弧度除以listViewitem的总数,然后通过ListView的滑动监听传入firstVisibleItem 来设置滑动块的起始角度 ,调用View的invalidate()的方法来重新绘制View.然而这种方法存在一个问题就是滑动块不能滑到滑动背景的底部,去掉背景效果会好点,但不美观,而且滑动块一格一格的跳,滑动效果太生硬了.产品经理一定会拍了我肩膀两下,说"小伙子还是老老实实给我弄个有背景又流畅的效果出来吧".


5.ListView本生不具备获取下拉滑动距离的方法,但可以从网上找到不少计算的方法.直接把滑动距离传进去就好了吗?答案当然不行.还需要计算每个弧度单位,类似上面的方法. 注意点:下拉获取的最大滑动距离并不是整个   item的高度 X item个数的距离   所以 每个弧度单位=滑动背景的总弧度应该 /(item X (item的总数-可见item的个数))[这个也只是与最大滑动距离接近而已],然后通过  每次的滑获取的距离 X 弧度单位 来确定 滑动块的起始角度,再通过invalidate()方法重新绘制来设定滑动块的位置.但这样也存在一个问题,因为 每个弧度单位 的获取不是通过 除以最大的滑动距离获得的,滑到底部时会存在要么滑动块超出范围,要么滑动块差一点才能滑到底部.  这时可以通过判断 当滑动距离>(item X (item的总数-可见item的个数)) 时,将滑动距离传入 ,重新计算 每个弧度单位,这样就可以 完美的避免了滑到底部的偏差.


6.滑动的问题是解决了,但往往特殊情况的解决才是重点, 例如item的总个数不满一屏时上面的方法是行不通的,当然通过不显示滑动条可以解决. 但当一屏的可见item是变化的例如总item=4, 可见item个数有3,4两种情况,这种判断条件.那么如何避免这种情况?我的方案是通过集合来收集可见item的情况来判断是否显示CricleScrollView, 条件如下

if(firstVisibleItem==0 && totalItemCount-1<visibleItemCount&&visibleItemNumber.size()==1),满足条件证明总item的个数 不满一屏,不显示CricleScrollView.


7.当写 5 的时候,获取ListView的子View时,在Activity的onCreate中获取是获取不到的,因为ListView获取子View需要在ListView 获取焦点后才能获得子View的, 所以需要将6 的步骤在 ListView 监听焦点变化的方法中初始化.





public class CircelScrollView extends ImageView {


private Context context;
private static Paint paintScroll=new Paint();
private static Paint paintBackgroud=new Paint();
private int mRadiu;//半径
private float mProgress;
private float mPreAngle;//每个item弧度
private float mRecfAngle;//弧长角度
private RectF mRect ;
private int mScrollState;
private int mScrollLength;
private int mScrollStroke;
private int maxListViewScrollY;
private int maxVisibleItemCount;
private boolean isScrollLast=false;
private ArrayList<Integer

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值