-
微信小程序 自定义下拉加载 对于ios弹性事件的处理
2019-03-18 14:37:52自己做了个下拉加载组件 ...发现:在ios弹性触发的情况下 微信的监听页面滑动事件(onPageScroll)的 e.scrollTop会出现负数,且 ios弹性会遮挡住隐藏view的出现 1.利用catch 判断下拉事件需要用到的三个事件, tou...自己做了个下拉加载组件 发现在ios弹性情况下不会出现预期的效果,在网上找了很久,自己也思考了很久总结了三个方法,来实现ios的兼容。
首先思考:ios为什么会出现情况?
发现:在ios弹性触发的情况下 微信的监听页面滑动事件(onPageScroll)的 e.scrollTop会出现负数,且 ios弹性会遮挡住隐藏view的出现1.利用catch
判断下拉事件需要用到的三个事件, touchstart(触摸开始),touchend(触摸结束),touchmove (触摸时)。当它们都使用catch时,发现ios是可以实现与安卓一样的效果(猜测:因为catch事件阻止了冒泡,所以iOS的弹性情况被catch遮挡住,阻止掉了)缺点:此事件会存在在catch事件包含内的事件无法点击
catchtouchstart="start_fn" catchtouchend="end_fn" catchtouchmove="move_fn"
2.在微信的.json配置"disableScroll": true
在需要用到的文件下的.json文件中配置"disableScroll": true (猜测:因为"disableScroll": true 的配置是定义了此页面不允许上下滑动,而阻止了ios的弹性)缺点:该页面将不能进行上下滑动
3.运用微信的animation 运用动画效果将被隐藏的view显示出来
onPageScroll: function (e) { if(e.scrollTop<-10){ this.data.index_scrollTop = false } },
const animation = wx.createAnimation({ duration: 10, timingFunction: 'step-start', }) this.animation = animation animation.translateY(-46).step() this.setData({ animation: animation.export() }) setTimeout(function () { animation.translateY(0).step() that.setData({ animation: animation.export() }) }, 1000)
-
云原生事件驱动弹性转码方案解析
2021-01-22 15:52:17事件驱动架构的核心是对系统上的各种事件做出反应并执行相应的动作。弹性伸缩已成为几乎所有云平台中不可或缺的组成部分。Kubernetes中,容器水平伸缩器HPA(Horizontal Pod Autoscaler)是最常用的应用弹性方案。...背景
在容器技术普及之前,事件驱动在数据库领域中被广泛使用。这个概念模型很简单:每当添加、更改或删除数据时,会触发一个事件来执行各种操作。事件驱动的方式可以在非常短的时间内,完成后续动作的执行。事件驱动架构的核心是对系统上的各种事件做出反应并执行相应的动作。弹性伸缩已成为几乎所有云平台中不可或缺的组成部分。Kubernetes中,容器水平伸缩器HPA(Horizontal Pod Autoscaler)是最常用的应用弹性方案。容器水平伸缩的核心是基于资源利用率与预设的阈值水位之间的关系,来确认伸缩的计划。容器水平伸缩的方式具有使用简单、资源指标丰富等特点,但是它对于需要即时弹性的场景,尤其是对基于事件源进行离线作业支撑不足。ACK提供了ack-keda来提供事件驱动弹性能力,事件驱动弹性适用于音视频离线转码、事件驱动作业、流式数据处理等场景。
事件驱动弹性原理
ACK通过增强版本的ack-keda来提供事件驱动弹性能力,下图是ack-keda的基本原理。
ack-keda会从事件源中进行数据的周期性消费。当消息出现堆积,即可秒级触发一个批次的离线任务伸缩。下一个周期到来时,会异步进行下一个批次的作业伸缩。ack-keda具有以下特性:
- 丰富的事件源
ack-keda内置支持Kafka、MySQL、PostgreSQL、Rabbitmq、Redis等多种内置数据源。同时支持从客户自定义的事件源获取事件并进行Job或者pod维度的弹性缩放。 - 离线任务的并发控制
对于大规模的离线作业而言,底层管控的稳定性会面临比较大的挑战,需要提供资源、额度、API请求的整体控制。ack-keda提供了单批次、总批次的任务并发控 制,保障系统的稳定性。 - 结束任务后自动清理元数据&&支持任务回溯
大规模离线作业执行完毕后,会留存大量的元数据信息。元数据信息的堆积会造成APIServer的稳定性下降,造成集群的性能下降、稳定性不足,甚至可能影响其 他的业务。ack-keda会在任务执行结束后自动清理元数据,降低元数据的量级。同时,ack-keda也支持保留一些执行失败的Job,便于回溯,定位原因。
事件驱动弹性转码案例
在本案例中,我们准备一个简单的转码作业,当有一个新任务到来的时候会向mongoDB插入一条类似下面的数据{"type":"mp4","state":"waiting","createTimeStamp":"1610332940","fileName":"World and peace","endTimeStamp":"","uuid":"1fae72ff-3239-42f5-af97-04711d8007e8"},此时,容器服务的事件驱动控制器会从数据库中查询到状态为"state":"waiting"的作业,弹出与任务数目匹配的Job Pod来承载转码作业,完成转码业务并将数据中的state字段从之前的waiting修改成finished。同时Job完成后,自动清理,降低元数据对APIServer带来的压力,极大的减轻开发者的负担。
1.安装事件驱动弹性控制器 - ack-keda
- 登录阿里云容器服务kubernetes控制台,点击左侧边栏的应用市场,搜索ack-keda
- 选择对应集群,点击部署,部署到该集群
- 选择左侧边栏的工作负载,选择无状态服务,选择kube-system 命名空间,确认ack-keda部署成功
2.部署基于mongoDB事件源驱动弹性示例
1.部署mongoDB
- 创建mongoDB.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: mongodb spec: replicas: 1 selector: matchLabels: name: mongodb template: metadata: labels: name: mongodb spec: containers: - name: mongodb image: mongo:4.2.1 imagePullPolicy: IfNotPresent ports: - containerPort: 27017 name: mongodb protocol: TCP --- kind: Service apiVersion: v1 metadata: name: mongodb-svc spec: type: ClusterIP ports: - name: mongodb port: 27017 targetPort: 27017 protocol: TCP selector: name: mongodb
- 执行kubectl apply -f mongoDB.yaml -n mongodb部署到集群。
2.mongoDB新建User
// 新建用户 kubectl exec -n mongodb mongodb-xxxxx -- mongo --eval 'db.createUser({ user:"test_user",pwd:"test_password",roles:[{ role:"readWrite", db: "test"}]})' // 登陆认证 kubectl exec -n mongodb mongodb-xxxxx -- mongo --eval 'db.auth("test_user","test_password")' // 新建collection kubectl exec -n mongodb mongodb-xxxxx -- mongo --eval 'db.createCollection("test_collection")'
3.部署TriggerAuthentication和ScaledJob
- 创建TriggerAuthentication
TriggerAuthentication是用来登录mongoDB查询数据时认证使用,TriggerAuthentication中的secretTargetRef字段会将指定Secret中的数据读取到ack-keda中,完成对Mongo的登录认证。
apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: mongodb-trigger spec: secretTargetRef: - parameter: connectionString name: mongodb-secret key: connect --- apiVersion: v1 kind: Secret metadata: name: mongodb-secret type: Opaque data: connect: bW9uZ29kYjovL3Rlc3RfdXNlcjp0ZXN0X3Bhc3N3b3JkQG1vbmdvZGItc3ZjLm1vbmdvZGIuc3ZjLmNsdXN0ZXIubG9jYWw6MjcwMTcvdGVzdA==
- 执行kubectl apply -f auth.yaml -n mongodb-test到集群。
- 创建ScaledJob
ScaledJob主要用来配置Job模板以及指定查询的数据库及查询表达式等,这里我们配置的是从test数据库中的test_collection中,查询满足{"type":"mp4","state":"waiting"}的待转码数据。
apiVersion: keda.sh/v1alpha1 kind: ScaledJob metadata: name: mongodb-job spec: jobTargetRef: // Job模板配置 template: spec: containers: - name: mongo-update image: registry.cn-hangzhou.aliyuncs.com/carsnow/mongo-update:v6 args: - --connectStr=mongodb://test_user:test_password@mongodb-svc.mongodb.svc.cluster.local:27017/test - --dataBase=test - --collection=test_collection imagePullPolicy: IfNotPresent restartPolicy: Never backoffLimit: 1 pollingInterval: 15 maxReplicaCount: 5 successfulJobsHistoryLimit: 0 failedJobsHistoryLimit: 10 triggers: - type: mongodb metadata: dbName: test //要查询的数据库 collection: test_collection //要查询的collection query: '{"type":"mp4","state":"waiting"}' //会对查询转码类型为mp4且状态是waiting的数据拉起job进行处理 queryValue: "1" authenticationRef: name: mongodb-trigger
- 执行kubectl apply -f scaledJob.yaml -n mongodb-test到集群。
4.插入待转码业务数据
// 插入5条待转码数据 kubectl exec -n mongodb mongodb-xxxxx -- mongo --eval 'db.test_collection.insert([ {"type":"mp4","state":"waiting","createTimeStamp":"1610352740","fileName":"My Love","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04711d8007e8"}, {"type":"mp4","state":"waiting","createTimeStamp":"1610350740","fileName":"Harker","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04711d8007e8"}, {"type":"mp4","state":"waiting","createTimeStamp":"1610152940","fileName":"The World","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04711d87767e8"}, {"type":"mp4","state":"waiting","createTimeStamp":"1610390740","fileName":"Mother","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04799d8007e8"}, {"type":"mp4","state":"waiting","createTimeStamp":"1610344740","fileName":"Jagger","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04711d80099e8"}, ])'
5.查看Job动态
// watch job watch -n 1 kubectl get job -n mongodb-test
可以看到成功扩展出5个Job。此时再登录数据库,观察转码业务状态,可以看到数据状态已经从waiting变成了finished。
写在最后
本文介绍的转码业务实际也是我们在日常场景经常会遇到的一个需求,看得出来ack-keda的使用,相对来说还是比较容易的,而且实际效果也能满足我们日常的需求。我们最近在keda社区的基础上,新增了对于mongoDB事件源的支持,并已PR到社区,至此,内置的事件源已经能够满足我们绝大部分事件驱动场景。
本文为阿里云原创内容,未经允许不得转载。
- 丰富的事件源
-
View的事件体系-弹性滑动
2018-04-02 15:41:29其实实现方法有很多,但它们都有一个共同思想:将一次大的滑动分成若干次小的滑动,并在一个事件内完成,弹性滑动的具体实现方式有很多,比如通过Scroller、Handler#postDelayed以及Thread#Sleep等,下面一一进行...知道了View的滑动,我们还要知道如何实现View的弹性滑动,比较生硬的滑动过去,这种方式的用户体验太差了,因此我们要实现渐进式滑动。那么如何实现弹性滑动呢?其实实现方法有很多,但它们都有一个共同思想:将一次大的滑动分成若干次小的滑动,并在一个事件内完成,弹性滑动的具体实现方式有很多,比如通过Scroller、Handler#postDelayed以及Thread#Sleep等,下面一一进行介绍。1.使用Scroller
Scroller在前面已经进行了介绍,下面我们来分析以下它的源码,从而探究为什么它能实现View的弹性滑动。Scroller scroller = new Scroller(mContext); //缓慢滑动到指定位置 private void smoothScrollTo(int destX,int destY){ int scrollX = getScrollX(); int deltaX = destX - scrollX; //1000ms内滑向destX,效果就是慢慢滑动 scroller.startScroll(scrollX,0,deltaX, 0,1000); invalidate(); } @Override public void computeScroll() { if (scroller.computeScrollOffset()) { scrollTo(scroller.getCurrX(), scroller.getCurrY()); postInvalidate(); } }
上面是Scroller的典型的使用方法,这里先描述它的工作原理:当我们构造一个Scroller对象并且调用它的startScroll方法时,Scroller内部其实什么也没有做,它只是保存了我们传递的几个参数,这几个参数从startScroll的原型上就可以看出来,如下所示。public void startScroll(int startX, int startY, int dx, int dy, int duration) { mMode = SCROLL_MODE; mFinished = false; mDuration = duration; mStartTime = AnimationUtils.currentAnimationTimeMillis(); mStartX = startX; mStartY = startY; mFinalX = startX + dx; mFinalY = startY + dy; mDeltaX = dx; mDeltaY = dy; mDurationReciprocal = 1.0f / (float) mDuration; }
这个方法的参数含义很清楚,startX和startY表示的是滑动的起点,dx和dy表示的是滑动的距离,而duration表示的是滑动的时间,即整个滑动过程完成所需要的时间,注意这里的滑动式指View内容的滑动而非View本身位置的改变。可以看到,仅仅调用startScroll方法式无法让View滑动的,因为它内部并没有做滑动的相关的事,那么Scroller到底事如何让View弹性滑动的呢?答案就是startScroll方法下面的invalidate方法,虽然有点不可思议,但是的确是这样的。invalidate方法导致View重绘,在View的draw方法中又会去调用computeScroll方法,computeScroll在View中是一个空实现,因此需要我们自己去实现,上面的代码已经实现了computeScroll方法。正是因为这个computeScroll方法,View才能实现弹性滑动。这看起来还是很抽象的,其实这样的:当View重绘后会在draw方法中调用computeScroll,而computeScroll又回去向Scroller获取当前的scrollX和scrollY;然后通过scrollTo方法实现滑动;接着又调用postInvalidate方法来进行第二次重绘,这一次的重绘过程和第一次重绘一样,还是会导致computeScroll方法被调用;然后继续向Scroller获取当前的scrollX和scrollY,并通过scrollTo方法滑动到新的位置,如此反复,直到整个滑动过程结束。我们再看以下Scroller的computeScrollOffset方法的实现,如下所示。public boolean computeScrollOffset() { if (mFinished) { return false; } int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime); if (timePassed < mDuration) { switch (mMode) { case SCROLL_MODE: final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal); mCurrX = mStartX + Math.round(x * mDeltaX); mCurrY = mStartY + Math.round(x * mDeltaY); break; case FLING_MODE: final float t = (float) timePassed / mDuration; final int index = (int) (NB_SAMPLES * t); float distanceCoef = 1.f; float velocityCoef = 0.f; if (index < NB_SAMPLES) { final float t_inf = (float) index / NB_SAMPLES; final float t_sup = (float) (index + 1) / NB_SAMPLES; final float d_inf = SPLINE_POSITION[index]; final float d_sup = SPLINE_POSITION[index + 1]; velocityCoef = (d_sup - d_inf) / (t_sup - t_inf); distanceCoef = d_inf + (t - t_inf) * velocityCoef; } mCurrVelocity = velocityCoef * mDistance / mDuration * 1000.0f; mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX)); // Pin to mMinX <= mCurrX <= mMaxX mCurrX = Math.min(mCurrX, mMaxX); mCurrX = Math.max(mCurrX, mMinX); mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY)); // Pin to mMinY <= mCurrY <= mMaxY mCurrY = Math.min(mCurrY, mMaxY); mCurrY = Math.max(mCurrY, mMinY); if (mCurrX == mFinalX && mCurrY == mFinalY) { mFinished = true; } break; } } else { mCurrX = mFinalX; mCurrY = mFinalY; mFinished = true; } return true; }
是不是突然就明白了?这个方法会根据时间的流逝来计算出当前的scrollX和scrollY的值。计算方法也很简单,大意就是根据时间流逝的百分比来算出scrollX和scrollY改变的百分比并计算出当前的值,这个过程类似与动画中的插值器的概念,这里我们先不去探究这个过程这个具体过程。这个方法的返回值也很重要,它返回true表示滑动未结束,false表示滑动已经结束,因此当这个方法返回tue时,我们要继续进行View的滑动。通过上面的分析,我们继续明白Scroller的工作原理,这里做一下概括:Scroller本身并不能实现View的滑动,它需要配合View的computeScroll方法才能完成弹性滑动的效果,它不断地让View重绘,而每一次重绘滑动其实时间会有一个时间间隔,通过这个时间间隔Scroller就可以得出View当前地滑动位置,知道了滑动位置就可以通过scrollTo方法来完成View滑动。就这样,View的每一次重绘都会导致View进行小幅度的滑动,而多次的小幅度滑动就组成了弹性滑动,这就是Scroller的工作机制。因此可见,Scroller的设计思想时多么值得称赞,这个过程中它对View没有丝毫的引用,甚至在它内部连计时器都没有。2.通过动画
动画本身就是一个渐近的过程,因此通过它来实现的滑动天然就具有弹性效果,比如以下代码可以让一个View的内容在100ms内向左移动100像素。ObjectAnimator.ofFloat(targetView,"translationX", 0,100).setDuration(100).start();
不过这里想说的并不是这个问题,我们可以利用动画的特性来实现一些动画不能实现的效果。还拿scrollTo来说,我们也想模仿Scroller来实现View的弹性滑动,那么利用动画的特性,我们可以采用如下方式来实现:final int startX = 0; final int deltaX = 100; ValueAnimator animator = ValueAnimator.ofInt(0,1).setDuration(1000); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float fraction = animation.getAnimatedFraction(); targetView.scrollTo(startX+(int)(deltaX*fraction),0); } }); animator.start();
在上述代码中,我们的公话本质上没有作用于任何对象上,他只是在1000ms内完成了整个动画过程。利用这个特性,我们就可以在动画的每一帧到来时获取动画完成的比例,然后再根据这个比例计算出当前View所要滑动的距离。注意,这里的滑动针对的是View的内容而非View本身。可以发现,这个方法的思想其实和Scroller比较类似,都是通过改变一个百分比配合scrollTo方法来完成View的滑动。需要说明的一点,采用这种方式除了能够完成滑动以外,还可以实现其他动画效果,我们完全可以再onAnimationUpdate方法中加上我们想要的其他操作。3.使用延时策略
本节介绍另外一种实现弹性滑动的方法,那就是延时策略。它的核心思想是通过发生一系列延时消息从而达到一种渐进式的效果,具体来说可以使用Handler或者View的postDelayed方法,也可以使用线程Sleep方法。对于postDelayed方法来说,我们可以通过它来延迟发送一个消息,然后再消息中来进行View的滑动,如果接连不断地发送这种延时消息,那么就可以实现弹性滑动的效果。对于sleep方法来说,通过在while循环中不断地滑动View和sleep,就可以实现弹性滑动的效果。下面采用Handler来左个示例,其他方法请自行去尝试,思想都是类似的。下面的代码大约1000ms内将View的内容向左移动了100像素代码比较简单,就不再详细介绍了。之所以说大约1000ms,是因为采用这种方式无法精确地定时,原因是系统的消息调度也是需要时间的,并且所需时间不定。
上面几种弹性滑动的实现方式,在介绍中侧重更多的是实现思想,在实际使用中可以对其灵活地进行扩展从而实现更多复杂地效果。private static final int MESSAGE_SCROLL_TO = 1; private static final int FRAME_COUNT = 30; private static final int DELAYED_TIME = 33; private int mCount = 0; private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case MESSAGE_SCROLL_TO: { mCount++; if (mCount <= FRAME_COUNT) { float fraction = mCount / (float)FRAME_COUNT; int scrollX = (int)(fraction*100); targetView.scrollTo(scrollX,0); mHandler.sendEmptyMessageDelayed(MESSAGE_SCROLL_TO,DELAYED_TIME); } break; } default: break; } } };
-
JavaScript值onload事件弹性方法
2018-07-29 10:54:09function addLoadEvent(func){ ...//用变量存储现有的事件处理函数 if(typeof window.onload!="function"){ window.onload=func; }else{ window.onload=function(){ oldonload(); func(); } }...function addLoadEvent(func){
var oldοnlοad=window.onload;//用变量存储现有的事件处理函数
if(typeof window.onload!="function"){
window.οnlοad=func;
}else{
window.οnlοad=function(){
oldonload();
func();
}
} -
eventeum:弹性的以太坊事件监听器,可将您的智能合约事件和后端微服务联系起来-源码
2021-02-05 07:51:52Eventeum 以太坊事件监听器,将您的智能合约事件和后端微服务联系... 弹性-检测到节点故障,一旦节点重新联机,事件订阅将从故障块继续。 叉子容忍度-Eventeum可以配置为等待一定数量的块,然后再将事件视为“已确认 -
鼠标事件,天猫弹性导航
2019-07-29 10:00:45onmouseover 鼠标进入 onmousemove鼠标移动 onmousedown 鼠标点击 onmouseout 鼠标离开 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">...meta name="viewport... -
事件分发:弹性滑动、滑动冲突
2016-09-19 14:41:04dispatchTouchEvent:用来进行事件的分发,如果事件能够传递给当前View,那么此方法一定会被调用,返回结果受当前View的onTouchEvent和View的dispatchTouchEvent方法的影响,表示是否当消耗当前事件 public boo -
使用keda完成基于事件的弹性伸缩
2020-09-14 15:05:27而在2.0增加了StatefulSet以及自定义资源 keda 是一个支持多种事件源来对应用进行弹性伸缩的控制器。我觉得keda可以认为是基于HPA的external metrics的一种扩展,因为它利用了hpa中external metrics的能力,允许直接... -
【android】View的事件体系3-弹性滑动
2017-05-23 22:21:133弹性滑动 1使用Scroller 2通过动画 3使用延时策略 3、弹性滑动View 的滑动如果过于...3.1、使用Scroller这个在View的事件体系1里面有,现在看它为什么能够实现view的弹性滑动。Scroller scroller = new Scroller(mC -
自动运维_弹性计算OOS事件驱动自动化运维
2021-01-15 09:00:37场景描述本方案适合Terraform的迁移用户或准备使用...解决问题事件驱动自动化运维。批量操作的运维场景。更新镜像的运维场景。需要审批的运维场景。定时任务的运维场景。跨地域、多地域运维。产品列表运维编排OOSDD... -
evebox, 在弹性搜索中,基于Web的事件查看器 ( GUI ) 用于 Suricata.zip
2019-09-18 07:32:41evebox, 在弹性搜索中,基于Web的事件查看器 ( GUI ) 用于 Suricata EveBox EveBox是基于web的用于弹性搜索的Suricata"eve"事件查看器 。 特性基于web的事件查看器,采用"收件箱"方法进行警报管理。事件搜索。将... -
《View的事件体系》(三)弹性滑动
2017-03-09 20:29:08在《View的事件体系》(二)中,我们介绍了几种实现View滑动的方法,可以看出实现起来并不复杂,但是实现效果略显生硬,最理想的是渐进式的滑动,也就是弹性滑动。实现弹性滑动的方法很多,但都是一个思想:就是把一... -
弹性及其应用 - 异想天开
2018-07-17 15:26:33弹性在系统论当中可以描述为弹性事件发生前的平衡系统状态和弹性事件发生后系统在某个时刻的系统状态对比。 1.需求弹性 需求弹性就是需求量对某种决定因素变动反应程度的指标。需求弹性的相关决定因素有:相近... -
View的事件体系(二)view的弹性滑动
2019-04-09 11:46:53上节主要总结了view的滑动和view的基础概念,这里就补充view的弹性滑动实现方式 弹性滑动方式 使用Scroller操作scrollTo/ScrollBy 使用动画 使用延时策略 一、Scroller的使用 1、使用步骤(固定): 1、 创建... -
微博应对突发热点事件的弹性调度实践
2018-03-12 00:00:00公众号推荐:公众号:VOA英语每日一听微信号: voahk01可长按扫码关注,谢谢 -
android-事件分发:弹性滑动、滑动冲突等
2016-01-06 15:37:11》弹性滑动 界面里滑动时的弹性效果应该叫什么?阻尼效果?界面的运动只是呈现了弹性的效果,并没有阻尼运动的特征。 总的来说,“由快到慢再到静止”这样的一种渐变效果,用「阻尼」来形容,都说得过去。... -
学习笔记:View的事件体系3:弹性滑动
2017-04-19 10:39:273种弹性滑动方式的学习 1、使用Scroller 2、使用动画 3、使用延时策略 一、使用ScrollerScroller scroller=new Scroller(mContext); //缓慢滚动到指定位置 private void smoothScrollTo(int destX,int destY){ ... -
仿豆瓣弹性滑动控件,史上最全方位讲解事件滑动冲突
2018-12-12 20:15:08同时也会消费左右滑动事件,左右滑动事件就会冲突。光是文字的描述,可能不大好理解,结合以下图片加以说明:手指向左滑动,是 RecyclerView 消费左滑的事件呢?还是 弹性滑动控件 消费左滑的事件? 垂直的... -
算法4的事件驱动问题。模拟弹性碰撞的问题
2019-07-23 20:56:27  那些公式是怎么来的? -
View的事件体系之--View的弹性滑动Scroller
2016-04-24 17:57:47上一篇说了View的几种滑动方式,但是哪几种方式滑动起来都比较生硬,没有弹性,这里介绍一种弹性滑动--Scroller。他的原理实际上就是:把一次大的滑动分成若干个小的滑动(而且这些每一次的小滑动并不是平均的,而是... -
View的事件体系之二 View的滑动以及弹性滑动
2018-01-12 16:43:23在Android设备上,滑动几乎是应用的标配,不管是下拉刷新还是recyclerView和listView等控件的滑动,他们的基础都是滑动,不管哪种滑动,首先他们滑动的基本思想是一致的:当触摸事件传到View时,系统记录下触摸点... -
Android ListView弹性效果,处理空ListView, 监听事件
2016-12-05 14:37:582.ListView的监听事件 setOnTouchListener my_list.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch ... -
第三章-View事件体系(View的滑动、弹性滑动)
2020-03-26 23:36:19弹性滑动 使用Scroller 通过动画‘ 使用延时策略 在上一节介绍了View的一些基础知识和概念,本节开始介绍很重要的一个内容:View的滑动。在Android设备上,滑动几乎是应用的标配,不管是下拉刷新还是SlidingMenu... -
View的事件体系(上)(View基础知识,滑动,弹性滑动)
2016-01-19 13:52:23View不是四大组件之一,但重要性堪比四大组件,本篇博文主要讲解View的事件体系,包括View的基础知识,滑动,弹性滑动,事件分发机制,滑动冲突的种类与解决方案。 一 View的基础知识 (1).View 的位置参数 View... -
View的事件体系---V3.3 弹性滑动
2016-04-17 23:41:12在View的onDraw方法中又会调用computeScroll方法,此方法内部调用ScrollTo方法进行滑动,同时又调用postInvalidate方法通知到View进行重绘,反复如此,完成View的弹性滑动,ps:此时完成的是View内容的滑动而非view...