亚洲精品亚洲人成在线观看麻豆,在线欧美视频一区,亚洲国产精品一区二区动图,色综合久久丁香婷婷

              當(dāng)前位置:首頁(yè) > IT技術(shù) > 移動(dòng)平臺(tái) > 正文

              Android 自定義ScrollView 支持慣性滑動(dòng),慣性回彈效果。支持上拉加載更多
              2021-08-10 19:06:30

              先講下原理:

              ScrollView的子View 主要分為3部分:head頭部,滾動(dòng)內(nèi)容,fooder底部

              我們實(shí)現(xiàn)慣性滑動(dòng),以及回彈,都是靠超過head或者fooder 就重新滾動(dòng)到? ,內(nèi)容的頂部或者底部。

              之前看了Pulltorefresh 他是通過不斷改變 head或者 fooder的 pading 值來實(shí)現(xiàn) 上拉或者 下拉的效果。感覺有點(diǎn)不流暢,而且層次嵌套得比較多。當(dāng)然他的好處是擴(kuò)展性好。

              因工作需求,需要層次嵌套少,對(duì)性能要求非常高。因此重新自定義了ViewGroup實(shí)現(xiàn)。

              Android 自定義ScrollView 支持慣性滑動(dòng),慣性回彈效果。支持上拉加載更多_android

              直接上代碼:

              1. package?com.example.administrator.customscrollview;??
              2. ??
              3. import?android.content.Context;??
              4. import?android.content.res.TypedArray;??
              5. import?android.util.AttributeSet;??
              6. import?android.util.Log;??
              7. import?android.view.Gravity;??
              8. import?android.view.MotionEvent;??
              9. import?android.view.VelocityTracker;??
              10. import?android.view.View;??
              11. import?android.view.ViewConfiguration;??
              12. import?android.view.ViewGroup;??
              13. import?android.widget.OverScroller;??
              14. ??
              15. /**?
              16. ?*?自定義?pulltorefresh?Layout?
              17. ?*?TODO:?ferris?2015年9月11日?18:52:40?
              18. ?*/??
              19. public?class?PullTorefreshScrollView?extends?ViewGroup?{??
              20. ??
              21. ????private?FoodeLayout?fooder_layout;//?top?and?buttom??
              22. ????private?View?top_layout;??
              23. ??
              24. ????private?int?desireWidth,?desireHeight;??
              25. ????private?VelocityTracker?velocityTracker;??
              26. ????private?int?mPointerId;??
              27. ????private?float?x,?y;??
              28. ????private?OverScroller?mScroller;??
              29. ????private?int?maxFlingVelocity,?minFlingVelocity;??
              30. ????private?int?mTouchSlop;??
              31. ????protected?Boolean?isMove?=?false;??
              32. ????protected?float?downX?=?0,?downY?=?0;??
              33. ????private?int?top_hight?=?0;??
              34. ????private?int?scrollYButtom?=?0;??
              35. ????private?int?nScrollYButtom?=?0;??
              36. ??
              37. ????private?int?pullDownMin?=?0;??
              38. ????private?Boolean?isEnablePullDown?=?true;??
              39. ??
              40. ????private?Boolean?isFirst=true;??
              41. ??
              42. ????public?void?setEnablePullDown(Boolean?isEnablePullDown)?{??
              43. ????????this.isEnablePullDown?=?isEnablePullDown;??
              44. ????}??
              45. ??
              46. ????public?PullTorefreshScrollView(Context?context)?{??
              47. ????????super(context);??
              48. ????????init(null,?0);??
              49. ????}??
              50. ??
              51. ????public?PullTorefreshScrollView(Context?context,?AttributeSet?attrs)?{??
              52. ????????super(context,?attrs);??
              53. ????????init(attrs,?0);??
              54. ????}??
              55. ??
              56. ????public?PullTorefreshScrollView(Context?context,?AttributeSet?attrs,?int?defStyle)?{??
              57. ????????super(context,?attrs,?defStyle);??
              58. ????????init(attrs,?defStyle);??
              59. ????}??
              60. ??
              61. ????private?void?init(AttributeSet?attrs,?int?defStyle)?{??
              62. ????????//?Load?attributes??
              63. //????????final?TypedArray?a?=?getContext().obtainStyledAttributes(??
              64. //????????????????attrs,?R.styleable.PullTorefreshScrollView,?defStyle,?0);??
              65. //??
              66. //??
              67. //????????a.recycle();??
              68. ????????mScroller?=?new?OverScroller(getContext());??
              69. ????????maxFlingVelocity?=?ViewConfiguration.get(getContext()).getScaledMaximumFlingVelocity();??
              70. ????????minFlingVelocity?=?ViewConfiguration.get(getContext()).getScaledMinimumFlingVelocity();??
              71. ????????mTouchSlop?=?ViewConfiguration.get(getContext()).getScaledTouchSlop();??
              72. ????}??
              73. ??
              74. ????@Override??
              75. ????protected?void?onFinishInflate()?{??
              76. ????????super.onFinishInflate();??
              77. ????????fooder_layout?=?(FoodeLayout)?findViewById(R.id.fooder_layout);??
              78. ????????top_layout?=?findViewById(R.id.top_layout);??
              79. ??
              80. ??
              81. ????????if?(isEnablePullDown)?{??
              82. ????????????fooder_layout.showFooderPull();??
              83. ????????}?else?{??
              84. ????????????fooder_layout.hideFooder();??
              85. ????????}??
              86. ????}??
              87. ??
              88. ??
              89. ????public?int?getScrollYTop()?{??
              90. ????????return?top_hight;??
              91. ????}??
              92. ??
              93. ????public?int?getScrollYButtom()?{??
              94. ????????return?scrollYButtom;??
              95. ????}??
              96. ??
              97. ????public?int?getNScrollYTop()?{??
              98. ????????return?0;??
              99. ????}??
              100. ??
              101. ????public?int?getNScrollYButtom()?{??
              102. ????????return?nScrollYButtom;??
              103. ????}??
              104. ??
              105. ????public?int?measureWidth(int?widthMeasureSpec)?{??
              106. ????????int?result?=?0;??
              107. ????????int?measureMode?=?MeasureSpec.getMode(widthMeasureSpec);??
              108. ????????int?width?=?MeasureSpec.getSize(widthMeasureSpec);??
              109. ????????switch?(measureMode)?{??
              110. ????????????case?MeasureSpec.AT_MOST:??
              111. ????????????case?MeasureSpec.EXACTLY:??
              112. ????????????????result?=?width;??
              113. ????????????????break;??
              114. ????????????default:??
              115. ????????????????break;??
              116. ????????}??
              117. ????????return?result;??
              118. ????}??
              119. ??
              120. ????public?int?measureHeight(int?heightMeasureSpec)?{??
              121. ????????int?result?=?0;??
              122. ????????int?measureMode?=?MeasureSpec.getMode(heightMeasureSpec);??
              123. ????????int?height?=?MeasureSpec.getSize(heightMeasureSpec);??
              124. ????????switch?(measureMode)?{??
              125. ????????????case?MeasureSpec.AT_MOST:??
              126. ????????????case?MeasureSpec.EXACTLY:??
              127. ????????????????result?=?height;??
              128. ????????????????break;??
              129. ????????????default:??
              130. ????????????????break;??
              131. ????????}??
              132. ????????return?result;??
              133. ????}??
              134. ??
              135. ????@Override??
              136. ????protected?void?onMeasure(int?widthMeasureSpec,?int?heightMeasureSpec)?{??
              137. ????????//?計(jì)算所有child?view?要占用的空間??
              138. ????????int?width?=?measureWidth(widthMeasureSpec);??
              139. ????????int?height?=?measureHeight(heightMeasureSpec);??
              140. ??
              141. ????????desireWidth?=?0;??
              142. ????????desireHeight?=?0;??
              143. ????????int?count?=?getChildCount();??
              144. ????????for?(int?i?=?0;?i?<?count;?++i)?{??
              145. ????????????View?v?=?getChildAt(i);??
              146. ??
              147. ????????????if?(v.getVisibility()?!=?View.GONE)?{??
              148. ??
              149. ????????????????LayoutParams?lp?=?(LayoutParams)?v.getLayoutParams();??
              150. ????????????????measureChildWithMargins(v,?widthMeasureSpec,?0,??
              151. ????????????????????????heightMeasureSpec,?0);??
              152. ??
              153. ????????????????//只是在這里增加了垂直或者水平方向的判斷??
              154. ????????????????if?(v.getId()?==?R.id.top_layout)?{??
              155. ????????????????????top_hight?=?v.getMeasuredHeight();??
              156. ????????????????}??
              157. ????????????????desireWidth?=?Math.max(desireWidth,?v.getMeasuredWidth()??
              158. ????????????????????????+?lp.leftMargin?+?lp.rightMargin);??
              159. ????????????????desireHeight?+=?v.getMeasuredHeight()?+?lp.topMargin??
              160. ????????????????????????+?lp.bottomMargin;??
              161. ??
              162. ????????????}??
              163. ????????}??
              164. ??
              165. ????????//?count?with?padding??
              166. ????????desireWidth?+=?getPaddingLeft()?+?getPaddingRight();??
              167. ????????desireHeight?+=?getPaddingTop()?+?getPaddingBottom();??
              168. ??
              169. ????????//?see?if?the?size?is?big?enough??
              170. ????????desireWidth?=?Math.max(desireWidth,?getSuggestedMinimumWidth());??
              171. ????????desireHeight?=?Math.max(desireHeight,?getSuggestedMinimumHeight());??
              172. ??
              173. ??
              174. ????????//處理內(nèi)容比較少的時(shí)候,就添加一定的高度??
              175. ????????int?scrollHight?=?height?+?top_hight?*?2;??
              176. ????????if?(scrollHight?>?desireWidth)?{??
              177. ????????????int?offset?=?scrollHight?-?desireHeight;??
              178. ????????????View?view?=?new?View(getContext());??
              179. ????????????view.setBackgroundResource(R.color.top_layout_color);??
              180. ????????????LayoutParams?lp?=?new?LayoutParams(LayoutParams.MATCH_PARENT,?offset);??
              181. ????????????addView(view,?getChildCount()?-?1,?lp);??
              182. ????????????desireWidth?=?scrollHight;??
              183. ????????}??
              184. ??
              185. ??
              186. ????????setMeasuredDimension(resolveSize(desireWidth,?widthMeasureSpec),??
              187. ????????????????resolveSize(desireHeight,?heightMeasureSpec));??
              188. ??
              189. ????????scrollYButtom?=?desireHeight?-?getMeasuredHeight()?-?top_hight;??
              190. ????????nScrollYButtom?=?desireHeight?-?getMeasuredHeight();??
              191. ????????//如果上啦拖出一半的高度,就代表將要執(zhí)行上啦??
              192. ????????pullDownMin?=?nScrollYButtom?-?top_hight?/?2;??
              193. ????????if(isFirst){??
              194. ????????????scrollTo(0,?top_hight);??
              195. ????????????isFirst=false;??
              196. ????????}??
              197. ??
              198. ????}??
              199. ??
              200. ????@Override??
              201. ????protected?void?onLayout(boolean?changed,?int?l,?int?t,?int?r,?int?b)?{??
              202. ????????final?int?parentLeft?=?getPaddingLeft();??
              203. ????????final?int?parentRight?=?r?-?l?-?getPaddingRight();??
              204. ????????final?int?parentTop?=?getPaddingTop();??
              205. ????????final?int?parentBottom?=?b?-?t?-?getPaddingBottom();??
              206. ??
              207. ????????if?(BuildConfig.DEBUG)??
              208. ????????????Log.d("onlayout",?"parentleft:?"?+?parentLeft?+?"???parenttop:?"??
              209. ????????????????????+?parentTop?+?"???parentright:?"?+?parentRight??
              210. ????????????????????+?"???parentbottom:?"?+?parentBottom);??
              211. ??
              212. ????????int?left?=?parentLeft;??
              213. ????????int?top?=?parentTop;??
              214. ??
              215. ????????int?count?=?getChildCount();??
              216. ????????for?(int?i?=?0;?i?<?count;?++i)?{??
              217. ????????????View?v?=?getChildAt(i);??
              218. ????????????if?(v.getVisibility()?!=?View.GONE)?{??
              219. ????????????????LayoutParams?lp?=?(LayoutParams)?v.getLayoutParams();??
              220. ????????????????final?int?childWidth?=?v.getMeasuredWidth();??
              221. ????????????????final?int?childHeight?=?v.getMeasuredHeight();??
              222. ????????????????final?int?gravity?=?lp.gravity;??
              223. ????????????????final?int?horizontalGravity?=?gravity??
              224. ????????????????????????&?Gravity.HORIZONTAL_GRAVITY_MASK;??
              225. ????????????????final?int?verticalGravity?=?gravity??
              226. ????????????????????????&?Gravity.VERTICAL_GRAVITY_MASK;??
              227. ??
              228. ??
              229. ????????????????//?layout?vertical,?and?only?consider?horizontal?gravity??
              230. ??
              231. ????????????????left?=?parentLeft;??
              232. ????????????????top?+=?lp.topMargin;??
              233. ????????????????switch?(horizontalGravity)?{??
              234. ????????????????????case?Gravity.LEFT:??
              235. ????????????????????????break;??
              236. ????????????????????case?Gravity.CENTER_HORIZONTAL:??
              237. ????????????????????????left?=?parentLeft??
              238. ????????????????????????????????+?(parentRight?-?parentLeft?-?childWidth)?/?2??
              239. ????????????????????????????????+?lp.leftMargin?-?lp.rightMargin;??
              240. ????????????????????????break;??
              241. ????????????????????case?Gravity.RIGHT:??
              242. ????????????????????????left?=?parentRight?-?childWidth?-?lp.rightMargin;??
              243. ????????????????????????break;??
              244. ????????????????}??
              245. ????????????????v.layout(left,?top,?left?+?childWidth,?top?+?childHeight);??
              246. ????????????????top?+=?childHeight?+?lp.bottomMargin;??
              247. ????????????}??
              248. ??
              249. ????????}??
              250. ??
              251. ??
              252. ????}??
              253. ??
              254. ????@Override??
              255. ????protected?android.view.ViewGroup.LayoutParams?generateDefaultLayoutParams()?{??
              256. ????????return?new?LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,??
              257. ????????????????ViewGroup.LayoutParams.MATCH_PARENT);??
              258. ????}??
              259. ??
              260. ????@Override??
              261. ????public?android.view.ViewGroup.LayoutParams?generateLayoutParams(??
              262. ????????????AttributeSet?attrs)?{??
              263. ????????return?new?LayoutParams(getContext(),?attrs);??
              264. ????}??
              265. ??
              266. ????@Override??
              267. ????protected?android.view.ViewGroup.LayoutParams?generateLayoutParams(??
              268. ????????????android.view.ViewGroup.LayoutParams?p)?{??
              269. ????????return?new?LayoutParams(p);??
              270. ????}??
              271. ??
              272. ????public?static?class?LayoutParams?extends?MarginLayoutParams?{??
              273. ????????public?int?gravity?=?-1;??
              274. ??
              275. ????????public?LayoutParams(Context?c,?AttributeSet?attrs)?{??
              276. ????????????super(c,?attrs);??
              277. ??
              278. ????????????TypedArray?ta?=?c.obtainStyledAttributes(attrs,??
              279. ????????????????????R.styleable.SlideGroup);??
              280. ??
              281. ????????????gravity?=?ta.getInt(R.styleable.SlideGroup_layout_gravity,?-1);??
              282. ??
              283. ????????????ta.recycle();??
              284. ????????}??
              285. ??
              286. ????????public?LayoutParams(int?width,?int?height)?{??
              287. ????????????this(width,?height,?-1);??
              288. ????????}??
              289. ??
              290. ????????public?LayoutParams(int?width,?int?height,?int?gravity)?{??
              291. ????????????super(width,?height);??
              292. ????????????this.gravity?=?gravity;??
              293. ????????}??
              294. ??
              295. ????????public?LayoutParams(android.view.ViewGroup.LayoutParams?source)?{??
              296. ????????????super(source);??
              297. ????????}??
              298. ??
              299. ????????public?LayoutParams(MarginLayoutParams?source)?{??
              300. ????????????super(source);??
              301. ????????}??
              302. ????}??
              303. ??
              304. ??
              305. ????/**?
              306. ?????*?onInterceptTouchEvent()用來詢問是否要攔截處理。?onTouchEvent()是用來進(jìn)行處理。?
              307. ?????*?<p/>?
              308. ?????*?例如:parentLayout----childLayout----childView?事件的分發(fā)流程:?
              309. ?????*?parentLayout::onInterceptTouchEvent()---false?--->?
              310. ?????*?childLayout::onInterceptTouchEvent()---false?--->?
              311. ?????*?childView::onTouchEvent()---false?--->?
              312. ?????*?childLayout::onTouchEvent()---false?--->?parentLayout::onTouchEvent()?
              313. ?????*?<p/>?
              314. ?????*?<p/>?
              315. ?????*?<p/>?
              316. ?????*?如果onInterceptTouchEvent()返回false,且分發(fā)的子View的onTouchEvent()中返回true,?
              317. ?????*?那么onInterceptTouchEvent()將收到所有的后續(xù)事件。?
              318. ?????*?<p/>?
              319. ?????*?如果onInterceptTouchEvent()返回true,原本的target將收到ACTION_CANCEL,該事件?
              320. ?????*?將會(huì)發(fā)送給我們自己的onTouchEvent()。?
              321. ?????*/??
              322. ????@Override??
              323. ????public?boolean?onInterceptTouchEvent(MotionEvent?ev)?{??
              324. ????????final?int?action?=?ev.getActionMasked();??
              325. ????????if?(BuildConfig.DEBUG)??
              326. ????????????Log.d("onInterceptTouchEvent",?"action:?"?+?action);??
              327. ??
              328. ????????if?(action?==?MotionEvent.ACTION_DOWN?&&?ev.getEdgeFlags()?!=?0)?{??
              329. ????????????//?該事件可能不是我們的??
              330. ????????????return?false;??
              331. ????????}??
              332. ??
              333. ????????boolean?isIntercept?=?false;??
              334. ????????switch?(action)?{??
              335. ????????????case?MotionEvent.ACTION_DOWN:??
              336. ????????????????//?如果動(dòng)畫還未結(jié)束,則將此事件交給onTouchEvet()處理,??
              337. ????????????????//?否則,先分發(fā)給子View??
              338. ????????????????isIntercept?=?!mScroller.isFinished();??
              339. ????????????????//?如果此時(shí)不攔截ACTION_DOWN時(shí)間,應(yīng)該記錄下觸摸地址及手指id,當(dāng)我們決定攔截ACTION_MOVE的event時(shí),??
              340. ????????????????//?將會(huì)需要這些初始信息(因?yàn)槲覀兊膐nTouchEvent將可能接收不到ACTION_DOWN事件)??
              341. ????????????????mPointerId?=?ev.getPointerId(0);??
              342. //??????????if?(!isIntercept)?{??
              343. ????????????????downX?=?x?=?ev.getX();??
              344. ????????????????downY?=?y?=?ev.getY();??
              345. //??????????}??
              346. ????????????????break;??
              347. ????????????case?MotionEvent.ACTION_MOVE:??
              348. ????????????????int?pointerIndex?=?ev.findPointerIndex(mPointerId);??
              349. ????????????????if?(BuildConfig.DEBUG)??
              350. ????????????????????Log.d("onInterceptTouchEvent",?"pointerIndex:?"?+?pointerIndex??
              351. ????????????????????????????+?",?pointerId:?"?+?mPointerId);??
              352. ????????????????float?mx?=?ev.getX(pointerIndex);??
              353. ????????????????float?my?=?ev.getY(pointerIndex);??
              354. ??
              355. ????????????????if?(BuildConfig.DEBUG)??
              356. ????????????????????Log.d("onInterceptTouchEvent",?"action_move?[touchSlop:?"??
              357. ????????????????????????????+?mTouchSlop?+?",?deltaX:?"?+?(x?-?mx)?+?",?deltaY:?"??
              358. ????????????????????????????+?(y?-?my)?+?"]");??
              359. ??
              360. ????????????????//?根據(jù)方向進(jìn)行攔截,(其實(shí)這樣,如果我們的方向是水平的,里面有一個(gè)ScrollView,那么我們是支持嵌套的)??
              361. ??
              362. ????????????????if?(Math.abs(y?-?my)?>=?mTouchSlop)?{??
              363. ????????????????????isIntercept?=?true;??
              364. ????????????????}??
              365. ??
              366. ??
              367. ????????????????//如果不攔截的話,我們不會(huì)更新位置,這樣可以通過累積小的移動(dòng)距離來判斷是否達(dá)到可以認(rèn)為是Move的閾值。??
              368. ????????????????//這里當(dāng)產(chǎn)生攔截的話,會(huì)更新位置(這樣相當(dāng)于損失了mTouchSlop的移動(dòng)距離,如果不更新,可能會(huì)有一點(diǎn)點(diǎn)跳的感覺)??
              369. ????????????????if?(isIntercept)?{??
              370. ????????????????????x?=?mx;??
              371. ????????????????????y?=?my;??
              372. ????????????????}??
              373. ????????????????break;??
              374. ????????????case?MotionEvent.ACTION_CANCEL:??
              375. ????????????case?MotionEvent.ACTION_UP:??
              376. ????????????????//?這是觸摸的最后一個(gè)事件,無論如何都不會(huì)攔截??
              377. ????????????????if?(velocityTracker?!=?null)?{??
              378. ????????????????????velocityTracker.recycle();??
              379. ????????????????????velocityTracker?=?null;??
              380. ????????????????}??
              381. ????????????????break;??
              382. ????????????case?MotionEvent.ACTION_POINTER_UP:??
              383. ????????????????solvePointerUp(ev);??
              384. ??
              385. ????????????????break;??
              386. ????????}??
              387. ????????return?isIntercept;??
              388. ????}??
              389. ??
              390. ????private?void?solvePointerUp(MotionEvent?event)?{??
              391. ????????//?獲取離開屏幕的手指的索引??
              392. ????????int?pointerIndexLeave?=?event.getActionIndex();??
              393. ????????int?pointerIdLeave?=?event.getPointerId(pointerIndexLeave);??
              394. ????????if?(mPointerId?==?pointerIdLeave)?{??
              395. ????????????//?離開屏幕的正是目前的有效手指,此處需要重新調(diào)整,并且需要重置VelocityTracker??
              396. ????????????int?reIndex?=?pointerIndexLeave?==?0???1?:?0;??
              397. ????????????mPointerId?=?event.getPointerId(reIndex);??
              398. ????????????//?調(diào)整觸摸位置,防止出現(xiàn)跳動(dòng)??
              399. ????????????x?=?event.getX(reIndex);??
              400. ????????????y?=?event.getY(reIndex);??
              401. ????????????if?(velocityTracker?!=?null)??
              402. ????????????????velocityTracker.clear();??
              403. ????????}??
              404. ????}??
              405. ??
              406. ????@Override??
              407. ????public?boolean?onTouchEvent(MotionEvent?event)?{??
              408. ??
              409. ????????final?int?action?=?event.getActionMasked();??
              410. ??
              411. ????????if?(velocityTracker?==?null)?{??
              412. ????????????velocityTracker?=?VelocityTracker.obtain();??
              413. ????????}??
              414. ????????velocityTracker.addMovement(event);??
              415. ??
              416. ????????switch?(action)?{??
              417. ????????????case?MotionEvent.ACTION_DOWN:??
              418. ????????????????//?獲取索引為0的手指id??
              419. ??
              420. ??
              421. ????????????????isMove?=?false;??
              422. ????????????????mPointerId?=?event.getPointerId(0);??
              423. ????????????????x?=?event.getX();??
              424. ????????????????y?=?event.getY();??
              425. ????????????????if?(!mScroller.isFinished())??
              426. ????????????????????mScroller.abortAnimation();??
              427. ????????????????break;??
              428. ????????????case?MotionEvent.ACTION_MOVE:??
              429. ????????????????isMove?=?true;??
              430. ????????????????//?獲取當(dāng)前手指id所對(duì)應(yīng)的索引,雖然在ACTION_DOWN的時(shí)候,我們默認(rèn)選取索引為0??
              431. ????????????????//?的手指,但當(dāng)有第二個(gè)手指觸摸,并且先前有效的手指up之后,我們會(huì)調(diào)整有效手指??
              432. ??
              433. ????????????????//?屏幕上可能有多個(gè)手指,我們需要保證使用的是同一個(gè)手指的移動(dòng)軌跡,??
              434. ????????????????//?因此此處不能使用event.getActionIndex()來獲得索引??
              435. ????????????????final?int?pointerIndex?=?event.findPointerIndex(mPointerId);??
              436. ????????????????float?mx?=?event.getX(pointerIndex);??
              437. ????????????????float?my?=?event.getY(pointerIndex);??
              438. ??
              439. ????????????????moveBy((int)?(x?-?mx),?(int)?(y?-?my));??
              440. ??
              441. ????????????????x?=?mx;??
              442. ????????????????y?=?my;??
              443. ????????????????break;??
              444. ????????????case?MotionEvent.ACTION_UP:??
              445. ????????????????isMove?=?false;??
              446. ????????????????velocityTracker.computeCurrentVelocity(1000,?maxFlingVelocity);??
              447. ????????????????float?velocityX?=?velocityTracker.getXVelocity(mPointerId);??
              448. ????????????????float?velocityY?=?velocityTracker.getYVelocity(mPointerId);??
              449. ??
              450. ????????????????completeMove(-velocityX,?-velocityY);??
              451. ????????????????if?(velocityTracker?!=?null)?{??
              452. ????????????????????velocityTracker.recycle();??
              453. ????????????????????velocityTracker?=?null;??
              454. ????????????????}??
              455. ????????????????break;??
              456. ??
              457. ????????????case?MotionEvent.ACTION_POINTER_UP:??
              458. ????????????????//?獲取離開屏幕的手指的索引??
              459. ????????????????isMove?=?false;??
              460. ????????????????int?pointerIndexLeave?=?event.getActionIndex();??
              461. ????????????????int?pointerIdLeave?=?event.getPointerId(pointerIndexLeave);??
              462. ????????????????if?(mPointerId?==?pointerIdLeave)?{??
              463. ????????????????????//?離開屏幕的正是目前的有效手指,此處需要重新調(diào)整,并且需要重置VelocityTracker??
              464. ????????????????????int?reIndex?=?pointerIndexLeave?==?0???1?:?0;??
              465. ????????????????????mPointerId?=?event.getPointerId(reIndex);??
              466. ????????????????????//?調(diào)整觸摸位置,防止出現(xiàn)跳動(dòng)??
              467. ????????????????????x?=?event.getX(reIndex);??
              468. ????????????????????y?=?event.getY(reIndex);??
              469. ????????????????????if?(velocityTracker?!=?null)??
              470. ????????????????????????velocityTracker.clear();??
              471. ????????????????}??
              472. ????????????????break;??
              473. ????????????case?MotionEvent.ACTION_CANCEL:??
              474. ????????????????isMove?=?false;??
              475. ????????????????break;??
              476. ????????}??
              477. ????????return?true;??
              478. ????}??
              479. ??
              480. ????private?Boolean?isPull?=?false;??
              481. ??
              482. ????//此處的moveBy是根據(jù)水平或是垂直排放的方向,??
              483. //來選擇是水平移動(dòng)還是垂直移動(dòng)??
              484. ????public?void?moveBy(int?deltaX,?int?deltaY)?{??
              485. ????????if?(BuildConfig.DEBUG)??
              486. ????????????Log.d("moveBy",?"deltaX:?"?+?deltaX?+?"????deltaY:?"?+?deltaY);??
              487. ????????if?(Math.abs(deltaY)?>=?Math.abs(deltaX))?{??
              488. ????????????int?mScrollY?=?getScrollY();??
              489. ????????????if?(mScrollY?<=?0)?{??
              490. ????????????????scrollTo(0,?0);??
              491. ????????????}?else?if?(mScrollY?>=?getNScrollYButtom())?{??
              492. ????????????????scrollTo(0,?getNScrollYButtom());??
              493. ??
              494. ??
              495. ????????????}?else?{??
              496. ????????????????scrollBy(0,?deltaY);??
              497. ????????????}??
              498. ??
              499. ????????????if?(isEnablePullDown?&&?deltaY?>?0?&&?mScrollY?>=?pullDownMin)?{??
              500. ????????????????isPull?=?true;??
              501. ????????????????Log.d("onlayout",?"isPull:?true");??
              502. ????????????}??
              503. ????????}??
              504. ??
              505. ??
              506. ????}??
              507. ??
              508. ????private?void?completeMove(float?velocityX,?float?velocityY)?{??
              509. ??
              510. ????????int?mScrollY?=?getScrollY();??
              511. ????????int?maxY?=?getScrollYButtom();??
              512. ????????int?minY?=?getScrollYTop();??
              513. ??
              514. ??
              515. ????????if?(mScrollY?>=?maxY)?{//如果滾動(dòng),超過了?下邊界,就回彈到下邊界??
              516. ??
              517. ????????????if?(isPull)?{//滾動(dòng)到最底部??
              518. ????????????????mScroller.startScroll(0,?mScrollY,?0,?getNScrollYButtom()?-?mScrollY,?300);??
              519. ????????????????invalidate();??
              520. ??
              521. ????????????????//顯示雷達(dá)??
              522. ????????????????fooder_layout.showFooderRadar();??
              523. ????????????????if?(pullDownListem?!=?null)?{??
              524. ????????????????????pullDownListem.onPullDown();??
              525. ????????????????}??
              526. ????????????????Log.d("onlayout",?"isPull:?true?滾動(dòng)到最底部,顯示出雷達(dá)");??
              527. ??
              528. ????????????}?else?{??
              529. ????????????????mScroller.startScroll(0,?mScrollY,?0,?maxY?-?mScrollY);??
              530. ????????????????invalidate();??
              531. ????????????????Log.d("onlayout",?"isPull:?true");??
              532. ????????????}??
              533. ??
              534. ????????}?else?if?(mScrollY?<=?minY)?{//如果滾動(dòng),超過了上邊界,就回彈到上邊界??
              535. ????????????//?超出了上邊界,彈回??
              536. ????????????mScroller.startScroll(0,?mScrollY,?0,?minY?-?mScrollY);??
              537. ????????????invalidate();??
              538. ????????}?else?if?(Math.abs(velocityY)?>=?minFlingVelocity?&&?maxY?>?0)?{//大于1頁(yè)的時(shí)候??
              539. //????????????mScroller.fling(0,?mScrollY,?0,?(int)?(velocityY?*?1.2f),?0,?0,?minY,?maxY);??
              540. ????????????mScroller.fling(0,?mScrollY,?0,?(int)?(velocityY?*?2f),?0,?0,?getNScrollYTop(),?getNScrollYButtom());??
              541. ????????????invalidate();??
              542. ????????}??
              543. ??
              544. ??
              545. ????}??
              546. ??
              547. ??
              548. ????public?void?ifNeedScrollBack()?{??
              549. ????????int?mScrollY?=?getScrollY();??
              550. ????????int?maxY?=?getScrollYButtom();??
              551. ????????int?minY?=?getScrollYTop();??
              552. ????????if?(mScrollY?>?maxY)?{??
              553. ????????????//?超出了下邊界,彈回??
              554. ????????????mScroller.startScroll(0,?mScrollY,?0,?maxY?-?mScrollY);??
              555. ??
              556. ????????????invalidate();??
              557. ??
              558. ????????}?else?if?(mScrollY?<?minY)?{??
              559. ????????????//?超出了上邊界,彈回??
              560. ????????????mScroller.startScroll(0,?mScrollY,?0,?minY?-?mScrollY);??
              561. ????????????invalidate();??
              562. ????????}??
              563. ????}??
              564. ??
              565. ????@Override??
              566. ????protected?void?onScrollChanged(int?l,?int?t,?int?oldl,?int?oldt)?{??
              567. ????????super.onScrollChanged(l,?t,?oldl,?oldt);??
              568. ????}??
              569. ??
              570. ????@Override??
              571. ????public?void?computeScroll()?{??
              572. ????????if?(mScroller.computeScrollOffset())?{??
              573. ??
              574. ????????????scrollTo(0,?mScroller.getCurrY());??
              575. ??
              576. ????????????postInvalidate();??
              577. ??
              578. ????????}?else?{??
              579. ????????????Log.d("onlayout",?"computeScroll,isMove:"+isMove+",isPull:"+isPull);??
              580. ????????????if?(!isMove?&&?!isPull)?{??
              581. ????????????????ifNeedScrollBack();??
              582. ????????????}??
              583. ??
              584. ????????}??
              585. ????}??
              586. ??
              587. ??
              588. ????public?void?onPullSuccess()?{??
              589. ??
              590. ????????soomToBack();??
              591. ????}??
              592. ??
              593. ????public?void?soomToBack()?{??
              594. ????????int?mScrollY?=?getScrollY();??
              595. ????????int?maxY?=?getScrollYButtom();??
              596. ????????Log.d("onlayout",?"soomToBack:?(maxY?-?mScrollY)="+(maxY?-?mScrollY)+",maxY="+maxY+",mScrollY="+mScrollY);??
              597. ????????//?超出了下邊界,彈回??
              598. ????????mScroller.startScroll(0,?mScrollY,?0,?maxY?-?mScrollY,?300);??
              599. ????????invalidate();??
              600. ????????postDelayed(new?Runnable()?{??
              601. ????????????@Override??
              602. ????????????public?void?run()?{??
              603. ????????????????fooder_layout.showFooderPull();??
              604. ????????????????isPull?=?false;??
              605. ????????????}??
              606. ????????},?310);??
              607. ??
              608. ??
              609. ????}??
              610. ??
              611. ????private?PullDownListem?pullDownListem;??
              612. ??
              613. ????public?void?setPullDownListem(PullDownListem?pullDownListem)?{??
              614. ????????this.pullDownListem?=?pullDownListem;??
              615. ????}??
              616. ??
              617. ????public?interface?PullDownListem?{??
              618. ??
              619. ????????public?void?onPullDown();??
              620. ??
              621. ????}??
              622. }?

              本文摘自 :https://blog.51cto.com/u

              開通會(huì)員,享受整站包年服務(wù)立即開通 >