自定義控件實現-今日頭條圖集效果
前提
產品有個新需求,類似今日頭條的圖集效果
大致看了下UI,大致就是ViewPager,橫向滑動切換圖片,縱向滑動移動圖片,縱向超過一定距離,圖片飛出,圖集淡出動畫退出,支持圖片的雙擊放大。
思路
第一個問題就是圖集詳情頁用什麽實現?Activity?Fragment?還是一個復雜的View?
我最初打算用Fragment的,因為覺得效率高,Fragment需要自己處理進入退出,
今日頭條使用了Activity,因為這個Activity可以顯示前一個Activity,所以它一定是一個透明的Activity
這個用自定義的Activity主題就可以實現
用Android的Layout Inspector 工具查看今日頭條它的布局,使用到ViewPager
我也打算繼承ViewPager,然後處理不同的情況下的觸摸事件,實現需求
具體實現
1 定義一個透明的Activity:
AndroidManifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.lijian.FloatImage"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name="com.lijian.FloatImage.MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.lijian.FloatImage.ImagesActivity" android:theme="@style/ImagesAppDayTheme"> </activity> </application> </manifest>
可以看到,圖集詳情頁使用了ImagesActivity
它對應的主題是ImagesAppDayTheme,註意裏面的幾個關鍵參數,目的就是創建背景透明的Activity:
<!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> <style name="ImagesAppDayTheme" parent="AppTheme"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> <item name="android:windowBackground">@color/transparent</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowAnimationStyle">@android:style/Animation</item> </style>
2 繼承ViewPager的FloatViewPager
普通的ViewPager不能滿足我們的需要,因為它只支持橫向滑動切換。我們需要處理其他方向的觸摸事件,然後處理。
這裏我直接重寫了ViewPager的public boolean dispatchTouchEvent(MotionEvent ev) { }方法,
為什麽呢?因為這裏是ViewPager觸摸事件分發的起點,比起使用onTouchEvent方法更靈活,方便。
我們知道一個完整的觸摸操作一般
由 ActionDown-》多個ActionMove-》ActionUp組成
我們需要判斷這個觸摸操作到底是橫向的還是縱向的,
如果是橫向的,直接調用父類ViewPager
return super.dispatchTouchEvent(ev);,由它處理橫向切換即可
對於縱向的觸摸:
我們需要計算觸摸的 X,Y的距離,然後移動ViewPager,實現跟隨手指的效果
如果手指擡起來,判斷移動距離,距離大於一個比例,就ViewPager整體移動飛出,圖集關閉
具體的實現,代碼都有註釋,如果你需要參考,清楚上述的思路,自己看代碼,修改,符合自己需求是最快的。授人魚不如授人漁
Github地址
https://github.com/bylijian/FloatImages
自定義控件實現-今日頭條圖集效果