滑動關閉activity

来源:http://www.cnblogs.com/tangZH/archive/2017/05/23/6896192.html
-Advertisement-
Play Games

對於微信滑動關閉activity的功能,我一直覺得挺酷,想在自己的項目上也加上這個功能。網上找了一下發現一個不錯的思路。 使用ViewDragHelper。 首先要讓activity在滑動的時候下麵的activity能夠看得到,那麼就得設置activity的主題,讓activity的視窗變透明。 該 ...


對於微信滑動關閉activity的功能,我一直覺得挺酷,想在自己的項目上也加上這個功能。網上找了一下發現一個不錯的思路。

使用ViewDragHelper。

首先要讓activity在滑動的時候下麵的activity能夠看得到,那麼就得設置activity的主題,讓activity的視窗變透明。

<style name="MyActivityBackground" parent="MyAppTheme">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowAnimationStyle">@android:style/Animation.Activity</item>
</style>

該主題繼承MyAppTheme(這也是個自定義的主題,整個application就是用這個主題,為了不避免衝突,繼承它)。
尤其要註意的是windowAnimationStyle,這個是設置activity的進入與退出的動畫效果,設置為預設的效果。

然後在需要實現滑動退出的activity的註冊文件上用上這個主題就行了。

 以下是全部代碼

public class MyDragViewGroup extends FrameLayout{

    private ViewDragHelper mViewDragHelper;

    //該自定義組件的寬
    private int mWidth;

    //該自定義組件的高
    private int mHeight;

    //需要滑動的組件目前已經滑動的距離
    private int currentLeft;

    //該滑動距離用於判斷是否可以將activity關閉
    private int mSlidX;

    private static final int x=40;
    private Context mContext;

    //需要滑動的view
    private View view;

    private Paint mPaint;

    public MyDragViewGroup(Context context) {
        super(context);
        initView(context);
    }

    public void bind()
    {
        //獲取activity的視圖
        ViewGroup viewGroup= (ViewGroup) ((Activity)mContext).getWindow().getDecorView();
        view=viewGroup.getChildAt(0);

        viewGroup.removeView(view); //將該視圖移除
        addView(view);  //將該視圖添加進去這個自定義的組件
        viewGroup.addView(this); //將該自定義的組件整個添加進decorView
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth=getMeasuredWidth();
        mHeight=getMeasuredHeight();
        mSlidX= (int) (mWidth*0.3);
    }

    private void initView(Context context)
    {
        mContext=context;

        mViewDragHelper=ViewDragHelper.create(this,callback);
        //邊緣檢測
        mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);

        mPaint=new Paint();
        mPaint.setStrokeWidth(2);
        mPaint.setAntiAlias(true);
        mPaint.setColor(Color.GRAY);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mViewDragHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mViewDragHelper.processTouchEvent(event);
        return true;
    }


    private ViewDragHelper.Callback callback=new ViewDragHelper.Callback() {
        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            return false;
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            return 0;
        }

        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            return left;
        }

        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);

            //如果滑動的距離小於mSlidX,那麼就滑回原處
            if (view.getLeft()<mSlidX)
            {
                mViewDragHelper.smoothSlideViewTo(view,0,0);
                ViewCompat.postInvalidateOnAnimation(MyDragViewGroup.this);
            }
            //否則滑出屏幕
            else
            {
                mViewDragHelper.smoothSlideViewTo(view,mWidth,0);
                ViewCompat.postInvalidateOnAnimation(MyDragViewGroup.this);
            }
            invalidate();
        }

        @Override
        public void onEdgeDragStarted(int edgeFlags, int pointerId) {
            mViewDragHelper.captureChildView(view,pointerId);
        }

        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            currentLeft=left;
            invalidate();
            if (left>=mWidth)
            {
                ((Activity)mContext).finish();
            }
        }
    };

    @Override
    public void computeScroll() {
        if (mViewDragHelper.continueSettling(true))
        {
            ViewCompat.postInvalidateOnAnimation(this);
            invalidate();
        }
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        drawShadow(canvas);
        super.dispatchDraw(canvas);
    }

    protected void drawShadow(Canvas canvas) {
        canvas.save();

        Shader mShader=new LinearGradient(currentLeft - x, 0, currentLeft, 0, new int[]{Color.parseColor("#1edddddd"),
                Color.parseColor("#6e666666"), Color.parseColor("#9e666666")}, null, Shader.TileMode.REPEAT);
        mPaint.setShader(mShader);
        //繪製時,註意向左邊偏移
        RectF rectF = new RectF(currentLeft - x, 0, currentLeft, mHeight);
        canvas.drawRect(rectF, mPaint);
        canvas.restore();
    }
}

如果知道ViewDragHelper的使用,那麼上面的代碼很容易看得明白。drawShadow()是為了繪製陰影,註意在滑動的過程中要不斷的刷新重繪,讓陰影跟隨著activity的移動而移動。

 

值得註意的是ViewGroup容器組件的繪製,當它沒有背景時直接調用的是dispatchDraw()方法, 而繞過了draw()方法,當它有背景的時候就調用draw()方法,而draw()方法里包含了dispatchDraw()方法的調用。因此要在ViewGroup上繪製東西的時候往往重寫的是dispatchDraw()方法而不是onDraw()方法,或者自定製一個Drawable,重寫它的draw(Canvas c)和 getIntrinsicWidth(), getIntrinsicHeight()方法,然後設為背景。

 

要使用的時候只需要在activity裡加入

MyDragViewGroup myDragViewGroup=new MyDragViewGroup(this); myDragViewGroup.bind();就OK了。

myDragViewGroup.bind();主要是將activity的視圖放入該自定義的ViewGroup當中,然後再把整個自定義的ViewGroup設置給activity。

參考博客:http://blog.csdn.net/meijian531161724/article/details/50763931


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 六、垂直居中-父元素高度確定的單行文本 1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>垂直居中</title> 6 <style> 7 8 .wrap h2{ 9 margin:0; 10 height:1 ...
  • Angular有5個大的組成部分: 1、控制器,2、路由,3、服務,4、篩選、5、指令 首先講服務: 服務要使用需要導入到控制器中。 自定義服務的方法: 然後是篩選器: 再是自定義指令 最後是路由:路由在上一章節已經講過,不再贅述。 ...
  • 1 $(function() { 2 $("#CheckMainCompany").change(function () { 3 if ($("#CheckMainCompany").is(':checked')) { 4 5 alert... ...
  • 1.滾動條預設是在html上的,移到body上 2.高清屏1px邊框還原 3.使用單位 px絕對單位,任何情況下都是固定值,在不同尺寸的屏幕下會錯位。 % 相對單位,相對於父級(自身)的大小進行計算。對於不太好確定值的地方(如高度)不好使用百分比,會導致變形。 em相對單位,相對於當前字體大小的倍數 ...
  • 關於表格寬度的渲染規則 表格單元格寬度的計算方式主要分為兩種方式:固定表格佈局、自動表格佈局,這個經常寫css的人應該還是知道的,但是我們經常會發現給表格列定了寬度不起作用,又或是沒有定寬度渲染出來的卻是正常的嗎,下麵就來介紹下這兩個方式具體是怎麼計算渲染的。 先設定幾個通用的變數: tableWi ...
  • 複製粘貼前隨手點個贊哦~~ //獲取地址欄參數 //url為空時為調用當前url地址 //調用方法為 var params = getPatams(); function getParams(url) { var theRequest = new Object(); if (!url) url = ... ...
  • 一、創建數組 使用 new 操作符調用構造函數 var arr = new Array(20) // 創建了一個包含20項的數組 var arr = new Array('a', 'b', 'c') // 創建了包含字元串 a b c 的三項數組 省略 new 操作符 var arr = Array ...
  • 效果圖如下: 1.activity_main.xml menu_shop_car_selected.png corner_view.xml 2.adapter_shopping_cart_item.xml 3.MainActivity 4.GoodsAdapter 5.GoodsModel http ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...