IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android-中心区域选中图表-WheelChart,必须试试 -> 正文阅读

[移动开发]Android-中心区域选中图表-WheelChart,必须试试

}
break;
case MotionEvent.ACTION_UP:
mActivePointerId = INVALID_ID;
mLastX = 0;

break;
case MotionEvent.ACTION_CANCEL:
mActivePointerId = INVALID_ID;
mLastX = 0;

break;
}
return true;
}

scrollBy方法内部会调用scrollTo方法,重写了scrollTo方法在里面进行一些选中下标的判断和最小最大滚动位置的拦截

@Override
public void scrollTo(int x, int y) {
//默认左边缘为x最小值-半个控件的宽度
if (x < mMinPosition) {
x = mMinPosition;
}
//默认右边缘为x最大值+半个控件的宽度
if (x > mMaxPosition) {
x = mMaxPosition;
}
if (x != getScrollX()) {
super.scrollTo(x, y);
}
mSelectIndex = scrollX2Index(x);
}

注意?在move事件中需要根据第一个触控点id计算移动距离,直接调用event.getX()方法,会有多点触控问题(复现步骤:一个手指滑动后,按下第二个手指,第一个手指抬起,view会自动滚动)

因为后面会有点击事件的判断,所以在move时判断如果移动距离小于IGNORE_MOVE_OFFSET = 2.5时,忽略,这样当手机滑动比较慢时,会有部分滑动事件被忽略掉的情况,不过2.5这个值自己滑动时觉得体验还可以,再大的话慢速滑动会有卡顿,太小的话点击事件的判定会过于精确。

4. 惯性滚动

惯性滚动的实现需要用到VelocityTracker计算up事件时的速度,OverScroller处理fling事件

主要思路是,当up事件发生时,判断手指速度,若速度小于最小值,scrollBackToExactPosition()直接将当前选中下标滚动到中心区域;若速度小于最大值按原速度计算否则按最大速度计算,根据此速度 当前x方向偏移量 可scrollTo的最小、最大值调用fling方法,并调用invalidate()方法,invalidate()内部几次回调会调用view的draw方法,在view的draw方法中调用computeScroll()方法,若惯性滚动未结束,调用scrollTo方法将view滚动到该速度应滚动到的位置,再调用postInvalidate(),几次回调又会重新调用view的draw方法,循环调用scrollTo将view再进行滚动 如此实现惯性滚动 直至滚动结束

5. 回滚

这个主要也是数学题,需要回滚的距离过大时,使用OverScroller慢速回滚,若过小则立刻回弹

//触摸事件或惯性滚动结束后 应滚动到中心位置
private void scrollBackToExactPosition() {
float rightPosition = mSelectIndex * mParent.getXLabelInterval() - (float) getWidth() / 2;
if (Math.abs(getScrollX() - rightPosition) > IGNORE_OFFSET) {
int dx = Math.round(rightPosition - getScrollX());
if (Math.abs(dx) > MIN_SCROLLER_DP) {
//渐变回弹
mOverScroller.startScroll(getScrollX(), getScrollY(), dx, 0, 500);
invalidate();
} else {
//立刻回弹
scrollBy(dx, 0);

6. 点击选中

点击事件的判定:最开始的想法是,判断事件如果是down紧接up即为点击,后来发现这种判定比较苛刻,因为有些点击事件会引起略微的move事件,所以在move事件中判断如果move距离较短,则忽略,这种方法的判定目前没有发现问题,如果大家有好的想法,欢迎讨论。

判定为点击事件后,要根据点击点的坐标位置和当前已滚动的距离,计算出点击点所在的下标,改变需要选中的下标,滚动到指定下标

7. 处理嵌套滚动

由于这个view是横向滚动的,避免被父View拦截事件,我们需要在横向滑动时拦截事件进行处理;在纵向滑动时不作拦截,交由父view AppBarLayout处理

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:

//记录首个触控点的id
mActivePointerId = event.findPointerIndex(event.getActionIndex());

mLastX = event.getX();
mLastY = event.getY();
parent.requestDisallowInterceptTouchEvent(false);//按下时开始让父控件不要处理任何touch事件
break;
case MotionEvent.ACTION_MOVE:
if (mActivePointerId == INVALID_ID || event.findPointerIndex(mActivePointerId) == INVALID_ID) {
break;
}
//计算首个触控点x方向移动距离
float moveX = mLastX - event.getX(mActivePointerId);
//计算首个触控点y方向移动距离
float moveY = mLastY - event.getY(mActivePointerId);
//判断x方向移动距离大于等于y方向距离 则判断为x轴滚动即滑动图表 反之判断为y轴滚动将事件交由父布局处理
if (Math.abs(moveX) >= Math.abs(moveY)) {
if (Math.abs(moveX) > IGNORE_MOVE_OFFSET) {
parent.requestDisallowInterceptTouchEvent(true);
mLastX = event.getX(mActivePointerId);

}
} else {
if (Math.abs(moveY) > IGNORE_MOVE_OFFSET) {
parent.requestDisallowInterceptTouchEvent(false);
mLastY = event.getY(mActivePointerId);
}
}
break;
case MotionEvent.ACTION_UP:
//判断是单点事件 跳转到指定位置

mActivePointerId = INVALID_ID;
mLastX = 0;
mLastY = 0;
parent.requestDisallowInterceptTouchEvent(false);//up或者cancel的时候恢复
break;
case MotionEvent.ACTION_CANCEL:

mActivePointerId = INVALID_ID;
mLastX = 0;
mLastY = 0;

parent.requestDisallowInterceptTouchEvent(false);//up或者cancel的时候恢复
break;
default:
mDownAndUp = false;
break;
}

这个控件的一点一个功能的实现,过程之中问题不断,问题解决又是惊喜,希望自己多些信心,多点努力,收拾行装,又上征程,加油,我们都是追梦人。

最后

针对Android程序员,我这边给大家整理了一些资料,包括不限于高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

  • Android前沿技术大纲

  • 全套体系化高级架构视频


好友一起学习!

  • Android前沿技术大纲

[外链图片转存中…(img-WnucxBHQ-1641134138897)]

  • 全套体系化高级架构视频

[外链图片转存中…(img-t1ZUs4pB-1641134138897)]

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-04 13:32:50  更:2022-01-04 13:35:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:40:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码