前提
產品有個新需求,類似今日頭條的圖集效果
大致看了下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整體移動飛出,圖集關閉
具體的實現,代碼都有注釋,如果你需要參考,清楚上述的思路,自己看代碼,修改,符合自己需求是最快的。授人魚不如授人漁