像知乎、iOS那样滑动Activity

这是Activity滑动的示意图

wKioL1ROVDLBj9MNAAXGth6htgA590.jpg

像fragment一样,activity本身是没有滑动的方法的,但是我们可以制造一个正在滑动activity的假象,使得这个activity看起来正在被手指滑动。其原理其实很简单,我们滑动的其实是activity里面的可见view元素,同时我们将activity设置为透明的,这样当activity中可见的view元素滑过的时候,由于activity的底部是透明的,我们就可以在滑动过程中看到下面的activity,这样看起来就是在滑动activity。所以activity滑动效果分两步,1,设置activity透明,2,滑动view。

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

    <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。

     

    要做到像iOS那样,可以滑动整个activity,只滑动我们在xml里面创建的view显然是不对的,因为我们还有标题栏、ActionBar什么的,所以我们要滑动的应该是DecorView或者倒数第二层的那个view。

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

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

    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);
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值