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中就能夠了。繼承

相關文章
相關標籤/搜索