前言:畢業之後在高薪的後廠村互聯網公司和生活工作平衡的體制內之間糾結了好久,最後選擇了後者,畢竟後廠村只要有技術什麼時候都能去,體制內基本上除了應屆生這次機會基本上就再也進不去了,社招就算進去也沒有編製。基於“面對兩難選擇時,選擇沒有體驗過的那個”的原則,選擇了體制,然後有幸被分配到了移動端開發的部 ...
前言:畢業之後在高薪的後廠村互聯網公司和生活工作平衡的體制內之間糾結了好久,最後選擇了後者,畢竟後廠村只要有技術什麼時候都能去,體制內基本上除了應屆生這次機會基本上就再也進不去了,社招就算進去也沒有編製。基於“面對兩難選擇時,選擇沒有體驗過的那個”的原則,選擇了體制,然後有幸被分配到了移動端開發的部門,以前積累的一點小知識算是沒有浪費。負責的這個app每天有幾千人用,雖然大家都在吐槽它速度慢,體驗差,bug多,適配不友好……但是如果你是他的客戶,你是不得不用的,因為……他管錢。
需求:體制內的程式還是以穩定為主,所以技術探索並不像後廠村的大廠一樣經常探索。現在一個需求就是解決ViewPager和webview輪播圖的滑動問題。看了一些博客我認為由js端傳給android端輪播圖的位置的解決方案體驗最好。但是由於種種原因,上級希望能夠android端本地解決。本地解決問題就來了,我怎麼知道webview裡面的輪播圖在哪裡?在我目前的知識儲備來看,單憑android端是做不到的。
解決方法:所以就想了一個本地的笨方法,把屏幕分割成左中右三份,從手指落地的位置開始算,在兩邊滑動就滑動ViewPager,在中間滑動就滑動webview輪播圖片。
兩個思路:一個是給webview添加onTouchListener,使用requestDisallowInterceptTouchEvent()方法告訴ViewPager要不要攔截。太簡單,會出現攔截不及時,輪播圖還會滑動一點,造成輪播圖卡住,不自動輪播,需要手動調整複位才能繼續輪播。我認為是js端的問題,但是無法解決。為什麼?如果能解決早就可以js端告訴android端輪播圖在哪了!
第二個思路就是重寫ViewPager的OnInterceptTouchEvent()方法,根據不同的情況對情況進行攔截。
第一步:ACTION_DOWN在兩邊OnInterceptTouchEvent()返回true,在中間返回false。嗯,這樣不會發生輪播圖滑動一點的情況了。可是,在兩邊的都攔截了,那在Fragment裡面兩邊的控制項 怎麼辦,沒法點擊了,被攔截了。
第二步:所以即使在兩邊也有不被攔截的情況。目前發現兩種,一種是點擊,一種是上下滑動。因為一個觸摸事件是先一個ACTION_DOWN,後面若幹個ACTION_MOVE,最後一個ACTION_UP。這個move只要手指在屏幕上就會一直調用,所以哪怕是點擊事件有時也會出現move。因為滑動時間和距離是一直增加的,所以就在move滑動時間和距離大於某個數之後return。經過調試和體驗,基本上達到了要求。
無法解決的問題:
如果一個fragment包含多個webview或其他控制項,一個webview只包括一個html控制項還好。如果一個fragment包含只包含一個大webview,大webview里是一個完整的網頁,甚至沒有輪播圖,那就造成即使在中間滑動也沒什麼用。這個問題只靠android端我現在還沒好的方案,哪個大神有可以賜教。
下麵貼出OnIntercepTouchEvent代碼
@Override public boolean onInterceptTouchEvent(MotionEvent event){ switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX=event.getX(); downY=event.getY(); downTime= System.currentTimeMillis(); if (downX< ScreenUtil.getScreenWidthPixels(getContext())/5||downX>ScreenUtil.getScreenWidthPixels(getContext())/5*4){ isIntercept=true; }else { isIntercept=false; return false; } break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_MOVE: long moveTime= System.currentTimeMillis(); float moveX=event.getX(); float moveY=event.getY(); if (isIntercept&&(Math.abs(moveY-downY)<20)&&((moveTime-downTime>300)||(Math.abs(moveX-downX)>9))){ return true; } if (isIntercept&&(Math.abs(moveY-downY)>=20)){ return false; } break; } return super.onInterceptTouchEvent(event); }