あなたが連関効果をスライディングマイクロチャネルのリターンを見て、その効果は、ドアを開くことですしている、ブラインド効果がそれを見て?

アンドロイドSmartSwipeがスリップ制御(のイベントカプセル化摺動ハンドルフレームであり、スライド4ジェスチャーイベントの上/下/左/右方向キャプチャ)、多点分布と置換処理スライドを、我々はSmartSwipeをベースとすることができあなたが効果をスリップしたいコントロールのさまざまなを追加します。

のは、それはそれを何ができるかを見てみましょう!

如果已经了解SmartSwipe的功能,只是想了解他的实现原理
可跳过第一节,直接看第二节的原理介绍

まず、使用状況やプレゼンテーション

グローバルスライディングリターンを達成するためのコードの1.1行

//仿手机QQ的手势滑动返回
SmartSwipeBack.activityStayBack(application, null);        
//仿微信带联动效果的透明侧滑返回
SmartSwipeBack.activitySlidingBack(application, null);    
//侧滑开门样式关闭activity
SmartSwipeBack.activityDoorBack(application, null);        
//侧滑百叶窗样式关闭activity
SmartSwipeBack.activityShuttersBack(application, null);    
//仿小米MIUI系统的贝塞尔曲线返回效果
SmartSwipeBack.activityBezierBack(application, null);

スライドのより多くの使用は、スタンプしてください返さこちら

レンダリング:

リターン効果をスライディング

ページを上に移動させるためのコードの1.2行

//为控件添加仿iOS的弹性留白效果:
//当纵向不能滚动(或滚动到顶/底)时,若继续拖动,则UI呈现弹性留白效果,释放后平滑恢复
SmartSwipe.wrap(view)
    .addConsumer(new SpaceConsumer())
    .enableVertical();

レンダリング:

弾性効果のブランク

ページを作成するためのコードの1.3弾性ライン

//为控件添加仿MIUI的弹性拉伸效果:
//当纵向不能滚动(或滚动到顶/底)时,若继续拖动,则UI呈现弹性拉伸效果,释放后平滑恢复
SmartSwipe.wrap(view)
    .addConsumer(new StretchConsumer())
    .enableVertical();

レンダリング:

弾性ストレッチ効果

リフレッシュするアドドロップダウンの1.4世代ライン

//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 drawerMode
behindMode behindMode
scaleMode scaleMode
translateMode translateMode

コードのスライディングメニューラインは1.5を追加しました

SmartSwipe.wrap(view)
    //添加抽屉效果,其效果与DrawerLayout相似
    //  DrawerLayout只支持左右2个方向,而DrawerConsumer支持上下左右4个方向
    .addConsumer(new DrawerConsumer())    
    //设置横向(左右两侧)的抽屉为同一个view(常见的侧滑显示删除按钮的功能)
    .setHorizontalDrawerView(buttonsViewGroup) 
    .setScrimColor(0x2F000000) //设置遮罩的颜色
    .setShadowColor(0x80000000)    //设置边缘的阴影颜色
    ;

レンダリング:

スライディングメニュー

1.6スライド可能な効果を連動メニューを追加するためにコードの行を有します

SmartSwipe.wrap(view)
    .addConsumer(new SlidingConsumer())
    .setRelativeMoveFactor(0.3F) //联动系数
    .setHorizontalDrawerView(buttonsView)
    .setScrimColor(0x2F000000)
    ;

レンダリング:

リンケージスライディングメニュー

クールなカバー1.7

SmartSwipe.wrap(coverView)
    .addConsumer(new ShuttersConsumer()) //百叶窗效果
    .setScrimColor(0xAF000000)
    .enableAllDirections()
    .addListener(new SimpleSwipeListener() {
        @Override
        public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
            //封面打开后自动隐藏或移除
            wrapper.setVisibility(View.GONE);
        }
    });

レンダリング:

ブラインドカバ​​ー

SmartSwipe.wrap(coverView)
    .addConsumer(new DoorConsumer()) //开门效果
    .setScrimColor(0xAF000000)
    .enableAllDirections()
    .addListener(new SimpleSwipeListener() {
        @Override
        public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
            //封面打开后自动隐藏或移除
            wrapper.setVisibility(View.GONE);
        }
    });

レンダリング:

オープンカバー

:カバーの詳細設定は、を参照してくださいデモ

第二に、実現原理

2.1まずViewDragHelperを紹介します

ViewDragHelperアンドロイドは公式ライブラリはユーティリティクラスを持ってサポートされています。それは私たちがドラッグアンドドロップのコントロールに対処することができます:カスタムのViewGroupを作成し、ドラッグされるコントロールがViewDragHelperコントロールに対処するために、こののViewGroupカスタム、ドラッグに追加されます。

主な役割ViewDragHelperにある:ドラッグ効果を達成するように、この子コントロールの左と上を変更することによって、親コンテナ内での位置を変更するために、子コントロールのドラッグをキャプチャするために、親コンテナのタッチイベントをインターセプト。

公式サポートライブラリ、関連するスライド引き出しSlidingPaneLayoutとDrawerLayout、およびBottomSheetBehaviorとSwipeDismissBehavior関連CoordinatorLayoutレイアウトでは、ViewDragHelperの姿を見ることができます。

但是,ViewDragHelper的名称也表明它就是用来处理拖拽的,拖拽的对象必须是一个子View,在拖拽的过程中需要改变子控件的left和top,对于一些没有子View被拖拽的侧滑效果(例如:MIUI系统的贝塞尔曲线侧滑返回效果、手机QQ的侧滑返回效果及MIUI官方app中的普遍使用了的弹性拉伸效果等等),却有点力有不逮。

2.2 借鉴ViewDragHelper实现侧滑处理

针对侧滑这个手势,我们能不能将它的概念抽象一下,到底侧滑指的是什么呢?

  • 狭义侧滑:从屏幕的某个边缘开始向着远离该边缘的方向滑动
  • 广义侧滑:手指在屏幕上按下之后向着某个方向滑动

我的理解是,广义侧滑包含狭义侧滑,只不过是触发区域是否在屏幕边缘的区别罢了。

既然侧滑手势能被明确地抽象出来,那么我们是否可以借鉴ViewDragHelper的事件拦截思路将它做这样的封装?

对被侧滑控件的touch事件进行拦截分析,确认是否将其捕获作为侧滑手势
然后计算好侧滑的实时位移(手指滑动的位移,而不是不依赖于View的left与top)
再通过策略模式(Strategy Pattern)使用不同的策略不断消费侧滑的位移来进行侧滑效果的UI呈现。

答案是肯定的!

2.3 SmartSwipe的实现原理

SmartSwipe在ViewDragHelper的基础上,将它对子View的捕获及移动处理改造成对父View自身触摸事件的定性(能否及是否捕获)、定向(捕获的事件所触发的侧滑方向)及定位(事件捕获之后在侧滑方向上移动的距离),并将侧滑距离交由SwipeConsumer来消费,SwipeConsumer根据侧滑距离的变化对控件布局进行相应的改变。

SmartSwipe的封装思路如下:

  • 用一个ViewGroup将需要处理侧滑事件的控件View包裹起来(被包裹起来的控件作为它的contentView
  • 可以为这个ViewGroup添加一些附属控件(如:滑动抽屉
  • タッチイベントとタッチイベントのこれのViewGroup傍受は消費のために離れてスリップに変換されSwipeConsumer
  • SwipeConsumer対応する変更制御摺動距離のレイアウトの変化に応じて
  • (コントロールのレイアウトを変更する継承SwipeConsumerを通じて、さまざまな方法:例えば、contentView位置及び補助制御、ズーム、透明度などを変更する)、様々な横滑りの効果を達成するようになっています。

したがって、ジェスチャ認識イベントを摺動離れスリップによれば、容易に継承SwipeConsumerを介して達成することができるレンダリング異なるUIの様々な達成するために、完了するために統一されたフレームワーク内距離演算作業をスライディング。

2.4どのようにカスタムSwipeConsumerを作成するには?

弾性フレーム建て模倣MIUIシステムアプリケーションケースのストレッチの効果を達成するために、

根据侧滑距离,对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);
            }
        }
    }
}

これは、弾性ストレッチの効果を達成するために、すべてのコードです非常に単純な、それはないですか?

その使用は同様に簡単です:

SmartSwipe.wrap(view) //指定目标控件
    .addConsumer(new StretchConsumer()) //添加弹性拉伸效果
    .enableVertical(); //指定工作方向为:上、下2个方向

模造携帯電話QQ横滑りリターン結果が達成方法を見てみましょう

手机QQ侧滑时UI没有任何变化
在手指释放时,根据滑动的方向和速率来决定是否finish当前Activity

コードは以下の通りであります:

public class StayConsumer extends SwipeConsumer {
    private int mMinVelocity = 1000;

    public StayConsumer() {
        //不能通过滑动距离判断是否需要打开
        setOpenDistance(Integer.MAX_VALUE)
                .setMaxSettleDuration(0); //打开时无需动画,时间置为0
    }

    @Override
    protected void onDisplayDistanceChanged(int distanceXToDisplay, int distanceYToDisplay, int dx, int dy) {
        //滑动时不需要对contentView做任何改变
    }

    @Override
    public void onSwipeReleased(float xVelocity, float yVelocity) {
        //在释放时,根据速率和方向来决定是否打开
        if (Math.abs(xVelocity) > Math.abs(yVelocity)) {
            if (mDirection == DIRECTION_LEFT && xVelocity >= mMinVelocity || (mDirection == DIRECTION_RIGHT && xVelocity <= -mMinVelocity)) {
                //置为打开状态
                mCurSwipeDistanceX = getSwipeOpenDistance();
                mProgress = 1;
            }
        } else {
            if (mDirection == DIRECTION_TOP && yVelocity >= mMinVelocity || (mDirection == DIRECTION_BOTTOM && yVelocity <= -mMinVelocity)) {
                //置为打开状态
                mCurSwipeDistanceY = getSwipeOpenDistance();
                mProgress = 1;
            }
        }
        super.onSwipeReleased(xVelocity, yVelocity);
    }

    public int getMinVelocity() {
        return mMinVelocity;
    }

    //支持使用者设置最低速率的阈值
    public StayConsumer setMinVelocity(int minVelocity) {
        if (minVelocity > 0) {
            this.mMinVelocity = minVelocity;
        }
        return this;
    }
}

また、非常に簡単です!

カスタムSwipeConsumer詳細な手順を作成するにはここをクリック

概要

この記事では、プロセスフレームとSmartSwipe実装原理をスライドを使用することを記載し、そして二つの例によるスリップの影響をカスタマイズする方法を紹介します。

複雑なスライド導入の効果を達成するために、テキストのちょうど例は、効果をスライドさせる比較的簡単で、読者必要な場合には、必要であれば、私は、別々に導入する別の記事を書くつもりです、私に一言コメントをお願いします!

また、スターそれは奨励し、支援するために最善であるオープンソースプロジェクトを!

おすすめ

転載: yq.aliyun.com/articles/709566