Activity滑动返回操做,像iOS的UINavigationController、知乎的Android版那样


这里只介绍原理,更详细的实现代码地址在此 :https://github.com/NashLegend/SwipetoFinishActivityandroid




这是Activity滑动的示意图git

wKioL1ROVDLBj9MNAAXGth6htgA590.jpg

像fragment同样,activity自己是没有滑动的方法的,可是咱们能够制造一个正在滑动activity的假象,使得这个activity看起来正在被手指滑动。其原理其实很简单,咱们滑动的实际上是activity里面的可见view元素,同时咱们将activity设置为透明的,这样当activity中可见的view元素滑过的时候,因为activity的底部是透明的,咱们就能够在滑动过程当中看到下面的activity,这样看起来就是在滑动activity。因此activity滑动效果分两步,1,设置activity透明,2,滑动view。github

  1. 设置透明: 创建一个Style,在Style里面添加下面两行,并将这个style应用在activity上就能够了ide

    <item name="android:windowBackground">@*android:color/transparent</item>
    <item name="android:windowIsTranslucent">true</item>
  2. 滑动view:先看看activity的层次结构:以下图,咱们用的activity的xml的根view(在下图中是倒数第二层的FrameLayout)并非activity的根view,在它上面还有一个父view,id是android.R.id.content,再向上一层,还有一个view,它是一个LinearLayout,它除了放置咱们建立的view以外,还放置咱们的xml以外的一些东西好比放ActionBar或者标题栏(在下图是左边那一分枝)。而再往上一级,就到了activity的根view——DecorView。this

     

    要作到像iOS那样,能够滑动整个activity,只滑动咱们在xml里面建立的view显然是不对的,由于咱们还有标题栏、ActionBar什么的,因此咱们要滑动的应该是DecorView或者倒数第二层的那个view。spa

    而要滑动view的话,咱们要重写其父窗口的onInterceptTouchEvent以及onTouchEvent【固然使用setOnTouchListener也能够,可是若是有一个子view消费了onTouch事件,那么也就接收不到了】,可是窗口的建立过程不是咱们能控制的,DecorView的建立都不是咱们能干预的。解决办法就是,咱们本身建立一个SwipeLayout,而后人为地插入到顶层view中,放置在DecorView和其下面的LinearLayout中间,随着手指的滑动,不断改变SwipeLayout的子view——曾经是DecorView的子view——的位置,这样咱们就能够控制咱们的滑动啦。orm

    咱们在自定义的SwipeLayout中添加一个replaceLayer,这个方法执行将SwipeLayout插入顶层的代码,并在activity的onPostCreate()方法中调用swipeLayout.replaceLaye()替换咱们的SwipeLayout,代码以下:xml

    public void replaceLayer(Activity activity) {
        mActivity = activity;
        screenWidth = getScreenWidth(activity);
        setClickable(true);
        ViewGroup root = (ViewGroup) activity.getWindow().getDecorView();
        content = root.getChildAt(0);
        ViewGroup.LayoutParams params = content.getLayoutParams();
        ViewGroup.LayoutParams params2 = new ViewGroup.LayoutParams(-1, -1);
        root.removeView(content);
        this.addView(content, params2);
        root.addView(this, params);
    }

而后咱们把这些写成一个SwipeActivity,其它activity只要继承这个SwipeActivity并设置上第一步中的style就能够实现滑动返回功能, 这里只说滑动activity的原理,剩下的都是控制滑动以及关闭Activity什么的事了,详见代码在这里:  摸我blog


BTW,滑动Fragment原理其实同样,只不过更加简单,省去替换那一步,Fragment在view树中就是它onCreateView返回的元素,用fragment.getView能够取得,滑动fragment其实滑动的就是fragment.getView。只要把滑动方法写在它父view中就能够了。继承

相关文章
相关标签/搜索