1. 程式人生 > >Android 滑動關閉Activity 示例

Android 滑動關閉Activity 示例

先看效果圖 :

要用到的 知識點 :1. 滑動處理 

       2.滑動衝突處理

       3.設定Activity的主題

       4. 位移動畫 

       5. 滑動的監聽

 明顯可以看出,它是一個ViewGrope , 而且肯定是在能看到的檢視最上層.(不然滑動過去了,背景不是透明的)。

那麼讓它繼承 RelativeLayout 並重寫其構造方法。

public class MySlipFinishView extends RelativeLayout {
    public MySlipFinishView(Context context) {
        super(context);
    }

    public MySlipFinishView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MySlipFinishView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}
然後重寫 onTouchEvent  方法:
 int startX = 0;
    int startY = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = (int) event.getRawX();
                startY = (int) event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                offX = (int) (event.getRawX() - startX);
                int offy = (int) (event.getRawX() - startY);
                if (Math.abs(offX) > ViewConfiguration.get(mContext).getScaledTouchSlop()) {
                    slipView(offX);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (Math.abs(offX) > (width / 2 - 5)) {
//                    Toast.makeText(mContext, "此時應該關閉當前Activity", Toast.LENGTH_SHORT).show();
                    if (mylayoutlisten != null) {
                        mylayoutlisten.closeActivitySlipListener();
                    }
                } else {
                    startObjectAnimation();
                }

                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }
在此方法中 確定滑動距離 , 然後根據距離判斷手擡起時,是否關閉當前Activity。 

說明 : 1.ViewConfiguration.get(mContext).getScaledTouchSlop() 獲取滑動最小距離。這樣體驗會好一點。

    2. width 是螢幕的寬度

 @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        width = getWidth();
    }

下面來實現 檢視根據手指滑動而滑動。我們常用的滑動有那麼幾種(layout ,偏移,layoutParams,scrollTo scrollBy , 動畫 等),這裡使用屬性動畫比較合適,因為此控制元件是整體滑動,而不是內容滑動!

屬性動畫程式碼如下:( 要匯入 com.nineoldandroids:library:2.4.0  jar)

private void slipViewGrope(int offX) {
        if (offX < 0) {
            offX = 0;
        }
        ViewHelper.setTranslationX(this, offX);
    }
 /**
     * 恢復到初始位置
     */
    private void startObjectAnimation() {
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(this, "translationX", 0);
        objectAnimator.setDuration(300);
        objectAnimator.start();
    }

 

設定監聽 : 要想使用還必須設定監聽,來監聽什麼時候關閉Activity。

public interface SlipActivityListener {
    void closeActivitySlipListener();
}

在控制元件中使用:

private SlipActivityListener myLayoutListener;

    public void setListener(SlipActivityListener listener) {
        this.myLayoutListener = listener;
    }
好了! 下面只要給Activity設定透明主題就行了 (透明不透明 隨個人 ,關鍵滑動了 Activity ,想看到什麼)
使用的Activity 要    <item name="windowBackground">@color/transparent</item>
                        <item name="colorBackgroundCacheHint">@null</item>
                        <item name="windowIsTranslucent">true</item>       要設定

如 :
<activity
            android:name=".SecondActivity"
            android:theme="@android:style/Theme.Translucent.NoTitleBar">
        </activity>

這樣基本就可以了。但是還有個問題沒有處理,滑動衝突。

新增如下程式碼就可以了。(判斷是否攔截)

 @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = (int) event.getRawX();
                startY = (int) event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                offX = (int) (event.getRawX() - startX);
                offY = (int) (event.getRawY() - startY);
                if (offX < 0) {
                    offX = 0;
                }
                if (Math.abs(offX) > (Math.abs(offY) + 10)) {
                    return true;
                } else {
                    return false;
                }
        }
        return super.onInterceptTouchEvent(event);
    }

到這裡就結束了,有什麼不對的,還請指出!

我在專案中使用的背景是:

  <item name="android:windowBackground">@color/transparent_left</item>
        <item name="android:colorBackgroundCacheHint">@color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>

 
 <color name="transparent_left">#50000000</color>
    <color name="transparent">#00000000</color>