Snake 滑動(dòng)關(guān)閉頁(yè)面

  • 在Fragment中使用必須繼承父類me.foji.snake.app.Fragmentme.foji.snake.v4.app.Fragment,并且要轉(zhuǎn)移布局代碼到onBindView中

為了克服這些問題,新版本將來(lái)到0.1.0脚曾。新版本不僅解決了上面兩個(gè)問題,而且對(duì)代碼進(jìn)行了簡(jiǎn)化杉适,去掉了冗余設(shè)計(jì)帖烘。同時(shí)钮惠,在靈活性上面有了大幅度的提高茅糜,可以讓你完全不要改動(dòng)原有代碼架構(gòu)就能使用滑動(dòng)關(guān)閉功能,真正的零侵入性設(shè)計(jì)素挽。廢話不多說(shuō)蔑赘,一起來(lái)看一下,怎么使用吧毁菱!

如何使用

1)添加依賴

dependencies {
    // Gradle高版本這里可以使用implementation代替compile
    // x.x.x代表最新版本號(hào)米死,請(qǐng)到文章底部點(diǎn)擊Github鏈接查看
    // 截止文章截稿日期,最新版本號(hào)都是0.1.0
    compile 'com.youngfeng.android:snake:x.x.x'
    annotationProcessor 'com.youngfeng.android:snake-compiler:x.x.x'
}

2) 在Application的onCreate方法中贮庞,對(duì)Snake進(jìn)行初始化

public class SnakeApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        Snake.init(this);
    }
}

3)在Activity中使用

  • 在需要使用滑動(dòng)關(guān)閉的Activity類頭添加@EnableDragToClose注解
@EnableDragToClose()
public class FirstActivity extends BaseActivity {

  • Activity.onCreate方法中,使用host接口對(duì)當(dāng)前Activity進(jìn)行托管
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Snake.host(this);
 }

以上兩個(gè)步驟已經(jīng)使Activity擁有了滑動(dòng)關(guān)閉功能究西,不相信嗎窗慎?試試看!

4)在Fragment中使用

  • 同樣地卤材,在需要使用滑動(dòng)關(guān)閉的Fragment類頭添加@EnableDragToClose注解
  • 如果是android.app.Fragment的子類遮斥,使用Snake.newProxy(FragmentA.class)創(chuàng)建當(dāng)前Fragment實(shí)例;如果是android.support.v4.app.Fragment的子類扇丛,使用Snake.newProxySupport(FragmentA.class)創(chuàng)建當(dāng)前Fragment實(shí)例术吗。

注意:Fragment類中不需要使用host接口對(duì)其進(jìn)行托管,Snake將自動(dòng)完成托管帆精。

通過以上四個(gè)步驟较屿,你已經(jīng)成功完成了對(duì)滑動(dòng)關(guān)閉的集成∽苛罚可是隘蝎,在不同的手機(jī)上測(cè)試,滑動(dòng)時(shí)你依然會(huì)發(fā)現(xiàn)幾個(gè)問題:

  • Activity中滑動(dòng)動(dòng)畫正常襟企,使用返回鍵回退和點(diǎn)擊進(jìn)入的動(dòng)畫卻表現(xiàn)不一致
  • Fragment中除了存在上述一樣的問題外嘱么,在滑動(dòng)關(guān)閉后,動(dòng)畫還會(huì)播放一次顽悼,導(dǎo)致整體看起來(lái)不和諧
    相信你應(yīng)該知道别凹,解決第一個(gè)問題其實(shí)很簡(jiǎn)單,只要在啟動(dòng)Activity和結(jié)束Activity的時(shí)候使用overridePendingTransition(R.anim.snake_slide_in_right, R.anim.snake_slide_out_left)設(shè)置動(dòng)畫即可赞弥,具體的設(shè)置可以參照 Github Demo進(jìn)行處理伐债。

而對(duì)于Fragment的設(shè)置相對(duì)較為麻煩,在啟動(dòng)的時(shí)候我們可以通過setCustomAnimation對(duì)其啟動(dòng)和回退動(dòng)畫進(jìn)行統(tǒng)一設(shè)置府蛇〖鳎可是在回退的時(shí)候,卻不能關(guān)閉某一次動(dòng)畫播放,導(dǎo)致了動(dòng)畫重復(fù)播放的問題务荆。為了避免這個(gè)問題妆距,Snake增加了wrapSnakeAnimationController兩個(gè)接口,通過這兩個(gè)接口聯(lián)合使用就可以避免這個(gè)問題函匕。

具體要怎么做呢娱据?看這里:

public class BaseFragment extends Fragment implements SnakeAnimationController {
    private boolean mDisableAnimation;

    @Override
    public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
        return Snake.wrap(super.onCreateAnimator(transit, enter, nextAnim), this);
    }

    @Override
    public void disableAnimation(boolean disable) {
        mDisableAnimation = disable;
    }

    @Override
    public boolean animationDisabled() {
        return mDisableAnimation;
    }
}

PS:重新onCreateAnimation的方式完全一致,Snakewrap接口也可以適用盅惜。

注意:這個(gè)操作強(qiáng)烈建議在Fragment基礎(chǔ)父類中進(jìn)行處理中剩,通過這種方式你也可以自己調(diào)用disableAnimation接口控制回退動(dòng)畫的播放。

以上幾個(gè)操作已經(jīng)完全可以正常使用滑動(dòng)關(guān)閉了抒寂〗崽洌可是,你可能還有一些特殊的需求屈芜,下面我通過QA的方式來(lái)模擬六種使用場(chǎng)景郊愧,如果還有沒有涵蓋的使用場(chǎng)景,請(qǐng)?jiān)谠u(píng)論下方告訴我井佑!

  • 場(chǎng)景一:如果我想對(duì)某個(gè)特殊的頁(yè)面禁用滑動(dòng)關(guān)閉属铁,需要怎么做?
    答:很簡(jiǎn)單躬翁,注解EnableDragToClose中可以接受一個(gè)Boolean參數(shù)焦蘑,用于控制滑動(dòng)關(guān)閉功能的開啟或關(guān)閉。因此盒发,你只需要這樣做就可以了例嘱!
@EnableDragToClose(false)
public class FirstActivity extends BaseActivity {

  • 場(chǎng)景二:如果我想對(duì)某個(gè)頁(yè)面動(dòng)態(tài)開啟或關(guān)閉,換句話說(shuō)迹辐,檢測(cè)到某些特殊情況開啟滑動(dòng)關(guān)閉功能蝶防,某些情況下禁用滑動(dòng)關(guān)閉功能,注解做不到吧明吩?Snake可以做到嗎间学?
    答:Snake已經(jīng)為你考慮到了這一點(diǎn),我們提供了接口enableDragToClose(Activity activity, boolean enable)印荔,Fragment參數(shù)也有同名接口低葫。因此,你只需要這樣做:
if(條件a) {
  Snake.enableDragToClose(this, true);
} else if(條件b) {
  Snake.enableDragToClose(this, false);
}

  • 場(chǎng)景三:想象這樣一種場(chǎng)景仍律,假設(shè)頁(yè)面中有視頻正在播放嘿悬,我想在滑動(dòng)開始后關(guān)閉視頻播放,結(jié)束播放繼續(xù)水泉,可以做到嗎善涨?
    答:當(dāng)然可以窒盐!為了滿足你對(duì)滑動(dòng)過程的控制,Snake提供了addDragListener(Activity activity, Snake.OnDragListener onDragListener)接口钢拧,用于監(jiān)聽整個(gè)滑動(dòng)過程的蟹漓。具體監(jiān)聽實(shí)現(xiàn),看這里:
  public static abstract class OnDragListener {
        public void onDragStart(View view) {}

        public void onDrag(View view, int left) {}

        public void onRelease(View view, float xVelocity) {}
    }

  • 場(chǎng)景四:如果在某些特殊場(chǎng)景下源内,頁(yè)面滑動(dòng)事件出現(xiàn)了沖突葡粒,是否有辦法補(bǔ)救?
    答:可以膜钓!為了防止在某些特殊場(chǎng)景下嗽交,滑動(dòng)事件出現(xiàn)沖突,Snake提供了接口public static void setCustomTouchInterceptor(@NonNull Activity activity, SnakeTouchInterceptor interceptor)實(shí)現(xiàn)對(duì)事件攔截的自定義處理颂斜。通常情況下夫壁,你不需要理會(huì)這個(gè)方法,如果確實(shí)發(fā)現(xiàn)是因?yàn)槭录_突問題導(dǎo)致了使用異常沃疮,才需要使用這個(gè)方法完成輔助處理掌唾。

  • 場(chǎng)景五:關(guān)于Fragment,我看到你使用了Snake.newProxy進(jìn)行了實(shí)例的創(chuàng)建忿磅。可是凭语,如果我有多個(gè)構(gòu)造方法呢葱她?或者說(shuō),我沒有提供默認(rèn)構(gòu)造方法實(shí)現(xiàn)似扔,怎么辦吨些?這種場(chǎng)景可以處理嗎?
    答:當(dāng)然可以炒辉!為了滿足對(duì)多構(gòu)造器實(shí)例創(chuàng)建的處理豪墅,Snake提供了一個(gè)新的注解@PrimaryConstructor用于指定主構(gòu)造器,指定后黔寇,Snake會(huì)以這個(gè)構(gòu)造器創(chuàng)建Fragment實(shí)例偶器,但這里要求你傳入構(gòu)造器所需的參數(shù),類似這樣:

Fragment fragment = Snake.newProxy(xx.class, objA, objB);

  • 場(chǎng)景六:說(shuō)了這么多缝裤,你似乎忽略了一個(gè)主流問題屏轰!如果我想對(duì)滑動(dòng)的樣式進(jìn)行設(shè)置,怎么辦憋飞?難道不允許嗎霎苗?
    答:這當(dāng)然也是允許的,不過不推薦你進(jìn)行自定義設(shè)置榛做,因?yàn)槟J(rèn)樣式已經(jīng)完全可以滿足需求了唁盏。但如果你一定要修改内狸,我也不反對(duì)。如果你要對(duì)全局進(jìn)行樣式修改厘擂,我們提供了snake.xml配置文件對(duì)樣式進(jìn)行設(shè)置昆淡。
<?xml version="1.0" encoding="utf-8"?>
<snake>
    <config>
        <!-- 設(shè)置為true,根Activity也能夠滑動(dòng)關(guān)閉驴党,這很奇怪瘪撇!不建議修改這個(gè)變量的默認(rèn)值 -->
        <enable_for_root_activity>false</enable_for_root_activity>
        <!-- 設(shè)置為true,將監(jiān)聽當(dāng)前頁(yè)面所有位置往右快速滑動(dòng)手勢(shì) -->
        <only_listen_to_fast_swipe>false</only_listen_to_fast_swipe>
        <!-- 快速滑動(dòng)最低檢測(cè)速度港庄,不建議修改倔既。過高會(huì)影響靈敏度,過低會(huì)導(dǎo)致誤判 -->
        <min_velocity>2000</min_velocity>
        <!-- 設(shè)置為true鹏氧,滑動(dòng)時(shí)左側(cè)邊緣陰影將被隱藏, 這個(gè)變量的默認(rèn)值也不建議修改 -->
        <hide_shadow_of_edge>false</hide_shadow_of_edge>
        <!-- 陰影邊緣漸變色起始顏色 -->
        <shadow_start_color>#00000000</shadow_start_color>
        <!-- 陰影邊緣漸變色結(jié)束顏色 -->
        <shadow_end_color>#55000000</shadow_end_color>
    </config>
</snake>

如果要對(duì)單個(gè)頁(yè)面進(jìn)行滑動(dòng)樣式修改渤涌,我們提供了@SetDragParameter注解:

    /**
     * 僅監(jiān)聽快速滑動(dòng)關(guān)閉
     */
    boolean onlyListenToFastSwipe() default false;

    /**
     * 快速滑動(dòng)最小檢測(cè)速度
     */
    int minVelocity() default 2000;

    /**
     * 隱藏陰影邊緣
     */
    boolean hideShadowOfEdge() default false;

    /**
     * 陰影起始顏色(陰影邊緣隱藏后,該設(shè)置失效)
     */
    String shadowStartColor() default "#00000000";

    /**
     * 陰影邊緣結(jié)束顏色(陰影邊緣隱藏后把还,該設(shè)置失效)
     */
    String shadowEndColor() default "#50000000";

注意:xml配置文件名必須是snake.xml实蓬,配置文件應(yīng)放置在assets目錄下面。

場(chǎng)景七:針對(duì)單個(gè)頁(yè)面逐一去開啟滑動(dòng)關(guān)閉功能實(shí)在太麻煩了吊履,是否可以針對(duì)所有頁(yè)面開啟滑動(dòng)關(guān)閉功能呢安皱?
答:當(dāng)然可以!首先艇炎,針對(duì)ActivityFragment你需要有一個(gè)統(tǒng)一的基類酌伊,使用方式與上文介紹完全一致。如果是Activity缀踪,先添加注解@EnableDragToClose居砖,然后在onCreate方法中使用host接口對(duì)其進(jìn)行托管,像這樣:

@EnableDragToClose()
public class BaseActivity extends Activity {

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Snake.host(this);
 }

}

如果是Fragment驴娃,同樣地奏候,先添加注解@EnableDragToClose,然后在跳轉(zhuǎn)到Fragment的時(shí)候使用Snake.newProxySnake.newProxySupport創(chuàng)建Fragment實(shí)例即可唇敞。

使用總結(jié)

為了讓你對(duì)整個(gè)使用過程有一個(gè)更直觀的了解蔗草,我用箭頭對(duì)整個(gè)過程做一個(gè)簡(jiǎn)單的總結(jié):

  • Application: Snake.init(this)
  • Activity: @EnableDragToClose => Snake.host(this) => 使用 overridePendingTransition 導(dǎo)入
    Snake 內(nèi)置動(dòng)畫
  • android.app.Fragment: @EnableDragToClose => Snake.newProxy(FragmentA.class) => implement SnakeAnimationControlleroverride onCreateAnimation or onCreateAnimator厚棵,return Snake.wrap(super.xxx)
  • android.support.v4.app.Fragment: @EnableDragToClose => Snake.newProxySupport(FragmentA.class) => implement SnakeAnimationController蕉世,override onCreateAnimation or onCreateAnimatorreturn Snake.wrap(super.xxx)

簡(jiǎn)單說(shuō)明

這里容易混淆的一個(gè)概念就是:注解@EnableDragToCloseSnake.enableDragToClose接口婆硬。其實(shí)狠轻,這兩個(gè)部分是有一定的區(qū)別的,注解是用于標(biāo)記當(dāng)前頁(yè)面是否需要開啟滑動(dòng)關(guān)閉功能彬犯,如果需要開啟向楼,注解始終需要查吊。但如果你希望當(dāng)前頁(yè)面始終關(guān)閉【滑動(dòng)關(guān)閉】功能,你可以在注解中傳入?yún)?shù)false湖蜕,而如果你希望動(dòng)態(tài)控制【滑動(dòng)關(guān)閉】功能的開啟或關(guān)閉逻卖,則需要使用Snake.enableDragToClose接口來(lái)控制。如果你沒有添加注解到類頭昭抒,直接使用接口開啟滑動(dòng)關(guān)閉功能评也,將會(huì)報(bào)錯(cuò)。

Snake版本兼容問題

Snake 0.1.0不兼容0.0.6極其以前版本灭返,如果你使用了舊版本實(shí)現(xiàn)盗迟,建議暫時(shí)不要替換,在新的APP中強(qiáng)烈推薦使用0.1.0及其以上版本熙含。

Android系統(tǒng)版本兼容問題

由于Android系統(tǒng)的一些限制罚缕,在低于21版本Activity滑動(dòng)聯(lián)動(dòng)的實(shí)現(xiàn)上有一些問題。為了避免這個(gè)問題怎静,我在低版本的使用上禁用了拖拽邮弹,僅使用快速滑動(dòng)關(guān)閉當(dāng)前頁(yè)面。這里我推薦使用全FragmentActivity + 多Fragment設(shè)計(jì)蚓聘。

在使用過程中腌乡,如果你有任何疑問,請(qǐng)點(diǎn)擊下方鏈接參考Github官方文檔:
https://github.com/yuanhoujun/Android_Slide_To_Close

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末夜牡,一起剝皮案震驚了整個(gè)濱河市导饲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌氯材,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件硝岗,死亡現(xiàn)場(chǎng)離奇詭異氢哮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)型檀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門冗尤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人胀溺,你說(shuō)我怎么就攤上這事裂七。” “怎么了仓坞?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵背零,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我无埃,道長(zhǎng)徙瓶,這世上最難降的妖魔是什么毛雇? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮侦镇,結(jié)果婚禮上灵疮,老公的妹妹穿的比我還像新娘。我一直安慰自己壳繁,他們只是感情好震捣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著闹炉,像睡著了一般蒿赢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上剩胁,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天诉植,我揣著相機(jī)與錄音,去河邊找鬼昵观。 笑死晾腔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的啊犬。 我是一名探鬼主播灼擂,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼觉至!你這毒婦竟也來(lái)了剔应?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤语御,失蹤者是張志新(化名)和其女友劉穎峻贮,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體应闯,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纤控,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碉纺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片船万。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖骨田,靈堂內(nèi)的尸體忽然破棺而出耿导,到底是詐尸還是另有隱情,我是刑警寧澤态贤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布舱呻,位于F島的核電站,受9級(jí)特大地震影響悠汽,放射性物質(zhì)發(fā)生泄漏狮荔。R本人自食惡果不足惜胎撇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望殖氏。 院中可真熱鬧晚树,春花似錦、人聲如沸雅采。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)婚瓜。三九已至宝鼓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間巴刻,已是汗流浹背愚铡。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胡陪,地道東北人沥寥。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像柠座,于是被迫代替她去往敵國(guó)和親邑雅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355