1. 程式人生 > >自定義控件實現-今日頭條圖集效果

自定義控件實現-今日頭條圖集效果

layout code 地址 ack cti https app 第一個 ret

前提

產品有個新需求,類似今日頭條的圖集效果
大致看了下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

自定義控件實現-今日頭條圖集效果