- 在Fragment中使用必須繼承父類
me.foji.snake.app.Fragment
或me.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
增加了wrap
和SnakeAnimationController
兩個(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
的方式完全一致,Snake
的wrap
接口也可以適用盅惜。
注意:這個(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ì)Activity
和Fragment
你需要有一個(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.newProxy
或Snake.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 SnakeAnimationController
,override onCreateAnimation or onCreateAnimator
厚棵,return Snake.wrap(super.xxx)
-
android.support.v4.app.Fragment:
@EnableDragToClose
=>Snake.newProxySupport(FragmentA.class)
=>implement SnakeAnimationController
蕉世,override onCreateAnimation or onCreateAnimator
,return Snake.wrap(super.xxx)
簡(jiǎn)單說(shuō)明
這里容易混淆的一個(gè)概念就是:注解@EnableDragToClose
和Snake.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è)面。這里我推薦使用全Fragment
或Activity + 多Fragment
設(shè)計(jì)蚓聘。
在使用過程中腌乡,如果你有任何疑問,請(qǐng)點(diǎn)擊下方鏈接參考Github官方文檔:
https://github.com/yuanhoujun/Android_Slide_To_Close