Androidサイドスライドはこんなに優雅だったのか


前言
サイドスライドジェスチャーはAndroid Appで広く応用されており、スライド引き出し、サイドスライド削除、サイドスライド戻り、ドロップダウンリフレッシュ、サイドスライド表紙など、一般的な使用シーンがあります.これらの使用シーンはあまりにも通用しているため、各道の大神たちは海を渡ってそれぞれ神通力を示しており、どのサイドスライドシーンも非常に実用的なフレームワークが多く、私たちの業務開発を便利にしています.
現在、各シーンに異なるサイドスライドフレームを導入する必要があります.Appのサイドスライドシーンが多いため、私たちのプロジェクトでは複数のサイドスライドフレームを導入する必要がありますが、フレームごとに使用方法が異なり、単独で学ぶ必要があり、チームの学習コストが高いです.
では、問題が発生しました.すべてのサイドスリップのニーズを解決できるフレームワークはありますか?
1つのフレームワークですべてのサイドスライドのニーズを解決しますか?冗談じゃないの?
オブジェクト向けプログラミングの概念を学び始めたばかりの頃、ソフトウェアの問題を解決するには、まず抽象化しなければならないという道理を知っていました.
サイドスライドというジェスチャーに対して、その概念を抽象化して、いったいサイドスライドは何を指しているのだろうか.
  • 狭義の側面スライド:スクリーンのある側のエッジからそのエッジから離れる方向にスライド
  • .
  • 広義のサイドスライド:指がスクリーン上で押す後、ある側の方向にスライド
  • .
    広義のサイドスライドには狭義のサイドスライドが含まれており、トリガ領域がスクリーンエッジにあるかどうかの違いにすぎないと理解しています.
    そこで,横滑りの概念はこのように明確に抽象化された.
               :               4         

    この抽象概念をカプセル化し,ジェスチャーイベントの識別,遮断およびデータ加工をフレームワーク内部で処理し,側面滑り方向,距離および関連するコールバックを外部にリアルタイムに出力すれば,理論的にはすべての側面滑り需要を実現できる.
             ,          :
                            。

    そんなでたらめなことを言っているのに,いったいどうしたのか.
    胸が上がって、息苦しい!刀を研いで柴刈りを間違えず、巨人の肩に立つと巨人より少し高くなる可能性があります.
    Googleはandroid supportライブラリでサイドスライドメニューのニーズにSlidingPaneLayoutとDrawerLayoutの2つの実装を提供しています.ソースコードを見ると、両方がViewDragHelperに基づいて実現されていることがわかりますが、ViewDragHelperはどこが神聖なのでしょうか.
    ViewDragHelperはandroid supportライブラリのツールクラスです.コントロールのドラッグを処理するのに役立ちます.まず、カスタムView Groupを作成し、このカスタムView Groupにドラッグされたコントロールを追加し、View DragHelperでコントロールのドラッグを処理します.Callbackでドラッグ領域を指定し、サブコントロールの論理をキャプチャできます.
    ViewDragHelperのソースコードを読むと、親コンテナでのviewのドラッグ動作がカプセル化されていることがわかります.親コンテナコントロールのジェスチャーイベントをブロックすることで、ドラッグする必要があるサブコントロールをキャプチャし、指の移動に応じて座標をリアルタイムで変更し、ドラッグ効果を実現します.
    ViewDragHelperパッケージは優雅で強力で、
    一部のオープンソース側滑りフレームワークも、ViewDragHelperに基づいて実現されます.たとえば、次のようになります.
    ikew0ng/SwipeBackLayout /  daimajia/AndroidSwipeLayout
    ただし、ViewDragHelperは、サイドスライドではなくサブコントロールのドラッグをカプセル化しています.距離の計算基準はコントロールのtop座標とleft座標です.一方の方向(横または縦)のドラッグ範囲を0に設定してサイドスライドジェスチャーをシミュレートできますが、私たちのサイドスライドジェスチャーの抽象的な定義に合わず、サイドスライド時にコントロールの移動ではない効果を解決できません.
    例えば、MIUIシステムの横滑りリターン効果や小米社が出品したAppで一般的に使用されている弾力性ストレッチ効果など
    そんなつまらないことを言うな,早く横滑りを話しなさい.
    サイドスライドが明確に抽象化されている以上、タッチスライドイベントの処理と同様に、ViewDragHelperの考えを完全に参考にすることができます:それをサブコントロールの捕獲とドラッグに変えて、サイドスライド方向の捕獲とサイドスライド距離の計算に変えて、そしてそのCallbackをサイドスライド距離の消費者に改造します(具体的な横滑り効果は消費者がどのような方法でこの横滑り距離を消費するかによって決まる).
    スライド動作の2つのコア要素:
    サイドスライド方向、サイドスライド距離
    この考え方に基づいて、私はスマートなサイドスライドフレームワークをパッケージしました:SmartSwipe、あなたの(chui)のある(bi)サイドスライドの需要を解決することができます.大きな声でsloganを言ってください!
    サイドスリップについては、これ一つあれば十分です
    もちろん、これはほらを吹くのです!
    フレームワークは横滑り行動イベントのキャプチャ、配布、多点交互スライドの処理をカプセル化しているだけで、具体的な横滑り効果(横滑り距離を消費する戦略)は自分で実現する必要があります...ああ..など、胸を上げて、先に行かないでください.まだ終わっていませんが、SmartSwipeには10種類以上のよく見られる横滑り効果が内蔵されています.
    1.1行のコードでページを動かす
    // iOS       :
    //            ,       
    SmartSwipe.wrap(view)
        .addConsumer(new SpaceConsumer())
        .enableVertical(); //    :  

    2.1行のコードはページに弾力性を持たせる
    // MIUI       :
    //            ,       
    SmartSwipe.wrap(view)
        .addConsumer(new StretchConsumer())
        .enableVertical(); //    :  

    3.1行のコードでスライド引き出しを追加する
    引き出しはメインビューの上に表示され、DrawerLayoutに似ています.
    SmartSwipe.wrap(view)
        .addConsumer(new DrawerConsumer())    //    
        //      (    )       view
        //               view
        .setHorizontalDrawerView(menuLayout) 
        .setScrimColor(0x2F000000) //       
        .setShadowColor(0x80000000)    //         
        ;

    4.1行コードに連動効果のあるスライド引き出しを追加
    引き出しがメインビューの下に表示されます
    SmartSwipe.wrap(view)
        .addConsumer(new SlidingConsumer())
        .setHorizontalDrawerView(textView)
        .setScrimColor(0x2F000000)
        //      
        //  0:   ,     :            
        //  0~1:    ,     :                       
        //  1:   ,     :          (pixel by pixel)
        .setRelativeMoveFactor(0.5F) 
        ;

    5.1行のコードでスライド透明効果を追加
    サイドスライド透明効果、サイドスライド後に遮蔽されたviewを表示することができ、サイドスライド削除として使用したり、表紙効果を作成したりすることができます
    //    
    SmartSwipe.wrap(view)
        .addConsumer(new TranslucentSlidingConsumer())
        .enableHorizontal() //        
        .addListener(new SimpleSwipeListener(){
            @Override
            public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                //     ,  
                ViewParent parent = wrapper.getParent();
                if (parent instanceof ViewGroup) {
                    ((ViewGroup) parent).removeView(wrapper);
                }
                //adapter.removeItem(getAdapterPosition());//      recyclerView     
            }
        })
        ;

    6.ワンラインコードにサイドスライドジェスチャー認識機能を追加
    サイドスライド時、メインviewは動かず、指が解放された場合、スライド方向と速度を認識し、対応するサイドスライドロジックを実行するかどうかを決定します.
    //demo: StayConsumer  activity    
    SmartSwipe.wrap(this)
        .addConsumer(new StayConsumer())
        .enableAllDirections()
        .addListener(new SimpleSwipeListener(){
            @Override
            public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                finish();
            }
        })
        ;

    7.1行のコードでブラインド効果を追加
    サイドスライド時にメインviewがブラインドのように開き、下層のビューが透明に表示されます.
    表紙や輪番図などを作るのに使えます
    // ShuttersConsumer         
    SmartSwipe.wrap(view)
        .addConsumer(new ShuttersConsumer())
        .enableHorizontal() //        
        .addListener(new SimpleSwipeListener(){
            @Override
            public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                //     ,  
                ViewParent parent = wrapper.getParent();
                if (parent instanceof ViewGroup) {
                    ((ViewGroup) parent).removeView(wrapper);
                }
                //adapter.removeItem(getAdapterPosition());//      recyclerView     
            }
        })
        ;

    8.1行のコードでドアを開ける効果を追加する
    横滑りすると、メインviewがドアを開けるように真ん中から両側(上下または左右)に分かれ、その下層のビューが透明に表示されます
    表紙や輪番図などを作るのに使えます
    // DoorConsumer         
    SmartSwipe.wrap(view)
        .addConsumer(new DoorConsumer())
        .enableHorizontal() //        
        .addListener(new SimpleSwipeListener(){
            @Override
            public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                //     ,  
                ViewParent parent = wrapper.getParent();
                if (parent instanceof ViewGroup) {
                    ((ViewGroup) parent).removeView(wrapper);
                }
                //adapter.removeItem(getAdapterPosition());//      recyclerView     
            }
        })
        ;

    9.1行のコードでベッセル曲線の戻り効果を追加
    サイドスライドの場合、コントロールのサイドスライドのエッジにベッセルカーブの戻り効果が表示されます.
    Activityリターン、fragmentリターン、webviewのリターン/前進に使用できます
    //activity    
    SmartSwipe.wrap(this)
        .addConsumer(new BezierBackConsumer())
        .enableAllDirections()
        .addListener(new SimpleSwipeListener() {
            @Override
            public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                finish();
            }
        })
        ;

    10.1行のコードに擬微信Activity連動側滑り戻り効果を追加
    そう、activityサイドスライドリターン専用の効果で、連動機能付き
    //activity    
    SmartSwipe.wrap(this)
        .addConsumer(new ActivitySlidingBackConsumer(this))
        //      
        .setRelativeMoveFactor(0.5F)
        //          , :enableLeft()         
        .enableAllDirections() 
        ;

    11.1行のコードにActivityブラインド側スライドバック効果を追加
    そうですね、activityの横滑りを戻すための効果でもあり、前のactivityを透明に表示します.
    //activity    
    SmartSwipe.wrap(this)
        .addConsumer(new ActivityShuttersBackConsumer(this))
        .setScrimColor(0x7F000000)
        .enableAllDirections()
        ;

    12.1行のコードにActivityを追加してドア側をスライドして戻る効果
    そう、これはactivityの横滑りのために返された効果で、前のactivityを透明に表示します.
    //activity    
    SmartSwipe.wrap(this)
        .addConsumer(new ActivitySlidingBackConsumer(this))
        .setRelativeMoveFactor(0.5F)
        .enableAllDirections()
        ;

    どうして1行のコードなの?もうちょっと来られないの?
    SmartSwipeのほとんどの使用は、チェーンプログラミングによって1行のコード内で行うことができます.APIの設計スタイルは以下の通りです.
    SmartSwipe.wrap(...)         //view or Activity
        .addConsumer(...)         //  consumer
        .enableDirection(...)     //  consumer           
        .setXxx(...)             //[  ]       
        .addListener(...);         //[  ] consumer    

    基本的な横滑り効果のほか、開発者が使いやすいようにツールクラス:SmartSwipeBackもパッケージされています. および SmartSwipeRefresh
    1行のコードでグローバルActivityロールバックを実現
  • グローバルは1行のコードだけですべてのActivityサイドスライドを
  • に戻すことができます.
  • オプションスタイル:ドアを開け、ブラインドを開け、微信を模倣し、QQを模倣し、MIUIベッセル曲線を模倣
  • 透明なトピックを必要としない
  • 特定のActivity
  • を継承する必要はありません.
  • xmlレイアウトファイル
  • に侵入する必要はありません.
  • もBaseActivity
  • に侵入する必要はありません
  • は、フルスクリーン側滑りおよび(/または)エッジ側滑りが
  • に戻ることをサポートする.
  • は、上下/左/右の4方向の横滑りをサポートし、
  • に戻る.
    //   QQ       
    SmartSwipeBack.activityStayBack(application, null);        
    //               
    SmartSwipeBack.activitySlidingBack(application, null);    
    //        activity
    SmartSwipeBack.activityDoorBack(application, null);        
    //         activity
    SmartSwipeBack.activityShuttersBack(application, null);    
    //   MIUI            
    SmartSwipeBack.activityBezierBack(application, null);

    行コード追加ドロップダウン・リフレッシュ機能
    任意のviewに使用可能
    //xxxMode      false,         :    &      
    //          true,          :    &      
    SmartSwipeRefresh.drawerMode(view, false).setDataLoader(loader);
    SmartSwipeRefresh.behindMode(view, false).setDataLoader(loader);
    SmartSwipeRefresh.scaleMode(view, false).setDataLoader(loader);
    SmartSwipeRefresh.translateMode(view, false).setDataLoader(loader);

    スタイル
    効果図
    drawerMode
    behindMode
    scaleMode
    translateMode
    Headerとfooterは、Ifxcyr/ArrowDrawableベースのArrowHeaderなど、サードパーティ製のクールなカスタムviewを使用できます.効果図は次のとおりです.
    見たところとてもdiaoの、しかし私の要した側は効果を滑ってあなたのここにありません
    SwipeConsumerをカスタマイズする必要があります.手順は次のとおりです.
  • クラスを新規作成し、SwipeConsumer
  • を継承
  • [オプション]構築方法でいくつかの初期化(contextオブジェクトが初期化する必要がある属性は、onAttachToWrapperメソッドで初期化できる)
  • を行う.
  • [オプション]追加のキャプチャロジックがある場合、親のtryAcceptMovingおよびtryAcceptSettlingメソッド
  • を書き換えることができる.
  • [オプション]onSwipeAcceptedメソッドを書き換えます.この場合、サイドスリップイベントがキャプチャされたことが決定され、サイドスリップの方向が決定されたため、今回のサイドスリップイベントの初期化作業
  • を行うことができます.
  • [オプション]clampDistanceHorizontalおよびclampDistanceHorizontalを書き換える方法は、一定の条件を満たす場合にのみ、本当にサイドスライド
  • を実行することができる.
  • onDisplayDistanceChangedメソッドを書き換え、具体的な横滑りを実行するUI効果は
  • を呈する.
  • [オプション]UIレンダリング効果にレイアウトコントロールの移動が含まれている場合は、onLayoutメソッドを書き換える必要があります.このメソッドでは、横滑り後の論理に従ってコントロールレイアウト位置決め
  • を行う必要があります.
  • onDetachFromWrapperメソッドを書き換え、現場を復元し、現在のconsumerのすべての変更痕跡
  • を除去する
    フレーム内蔵弾性引張効果Stretch Consumerを例に
          , contentView       ,          

    コードは次のとおりです.
    public class StretchConsumer extends SwipeConsumer {
        @Override
        public void onDetachFromWrapper() {
            super.onDetachFromWrapper();
            View contentView = mWrapper.getContentView();
            if (contentView != null) {
                contentView.setScaleX(1);
                contentView.setScaleY(1);
                contentView.setTranslationX(0);
                contentView.setTranslationY(0);
            }
        }
    
        @Override
        public void onDisplayDistanceChanged(int distanceXToDisplay, int distanceYToDisplay, int dx, int dy) {
            View contentView = mWrapper.getContentView();
            if (contentView != null) {
                if (distanceXToDisplay >= 0 && isLeftEnable() || distanceXToDisplay <= 0 && isRightEnable()) {
                    contentView.setScaleX(1 + Math.abs((float) distanceXToDisplay) / mWidth);
                    contentView.setTranslationX(distanceXToDisplay / 2F);
                }
                if (distanceYToDisplay >= 0 && isTopEnable() || distanceYToDisplay <= 0 && isBottomEnable()) {
                    contentView.setScaleY(1 + Math.abs((float) distanceYToDisplay) / mHeight);
                    contentView.setTranslationY(distanceYToDisplay / 2F);
                }
            }
        }
    }

    以上が弾性ストレッチ効果を実現するすべてのコードで、簡単ではないでしょうか.
    このように見ると、本当にすべてのサイドスライド効果を実現できるかもしれません.
    すべてのサイドスライド効果を実現するには理論的にしか存在しないが、必ず絶えず改善する必要がある.オープンソースが出てくるのもオープンソースコミュニティの力を利用して改善し、androidサイドスライドをもっと簡単にしたいと思っている.
    最後に、関連リンク先をお送りします.
    ソース: https://github.com/luckybilly/SmartSwipe
    ドキュメント: https://luckybilly.github.io/SmartSwipe-tutorial/ (gitbook形式で丹念に作成されています)
    Demoダウンロード: https://github.com/luckybilly/SmartSwipe/raw/master/app-release.apk
    著者:luckybilly
    原文を読む
    本文は雲栖コミュニティのオリジナル内容で、許可を得ずに転載してはならない.