不得不說現在技術迭代的非常快,之前很牛逼的想法、點子,現在覺得已經很槽糠了。
右滑返回在很多新項目中陸陸續續都加上了。該技術最早是ios上出現(如果我說錯了,輕點噴啊O(∩_∩)O哈哈~),後續再Android設備上出現,但是最早在2012年的時候還沒有那麼成熟的技術。用的很多都是通過監聽手勢OnGestureListener
與OnTouchListener
結合判斷手勢滑動方向,然後在添加一個平移動畫finish掉當前的界面。這有一個最大的缺點就是滑動時界面不能跟隨手指移動一起移動。經歷過這些的程序員每每想到這是不是都覺的就他媽的兩個字“青澀”
。現在技術日新月異,這些效果都不是個事情了。
首先我們看看現在有哪些好的滑動返回開源項目
- SwipeBackLayout github上star早已過千,並且很多項目也都是用了該開源庫。具體解說看着
- ParallaxBackLayout 視差滑動返回的 Activity,當然也是很牛逼的。
我們怎麼實現?
viewpager是我們經常在項目中用到的,當有多個界面切換時我們可以通過它實現並左右切換。對,下面就是主要思路了。我們使用viewpager添加兩個子view,其中第一個爲透明的,當然如果你想實現由陰影效果的也可以做成半透明的。第二個我們放入原本要放入的界面佈局。這樣,當我們每次打開頁面的時候顯示第二個子view,而當我們滑動viewpager的時候發現顯示的界面view是可以跟着手指滑動去移動的。
本項目github地址:SildBackSample
先看看效果圖:
來吧我們開始了
1. 我們需要展現佈局界面,所以需要傳入佈局Id,以及對viewpager子view進行加工,其中第一個view,是一個背景透明的view,第二個使我們傳入進來需要展示的view,並且進入該viewpager時我們要展示第二個view界面。
protected void initFramwork(Context context, View contentView) {
View localView = LayoutInflater.from(this).inflate(R.layout.temp, null);
localView.setBackgroundResource(android.R.color.transparent);
views.add(localView);
Drawable drawable = contentView.getBackground();
if (drawable == null) {
// contentView.setBackgroundColor(Color.parseColor("#fffafafa"));
contentView.setBackgroundResource(R.drawable.common_background);
}
views.add(contentView);
SildBaseAdapter localBaseAdapter = new SildBaseAdapter(views);
localViewPager.setAdapter(localBaseAdapter);
Message localMessage = Message.obtain();
localMessage.what = GOTO_CONTENTVIEW;
//開啓第二頁
baseHandler.sendMessageDelayed(localMessage, 200L);
//後續操作
}
2. 展示了第二個view,也就是我們看到的界面。當我們現在向右滑動來到第一個透明子view時。我們需要操作了,將該activity給finish掉。這樣我們才能操作上一個界面。
//設置滑動到上一頁時finish掉該activity
localViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
Log.e("onPageScrolled", "position:" + position);
if (position != 0)
return;
//當到第一頁時發送消息將當前activity finish掉
baseHandler.sendEmptyMessageDelayed(FINISH_ACTIVITY, 200L);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
3. 當我們點擊實體返回鍵或者點擊頁面左上角的返回按鈕、箭頭時我們同樣需要執行回到第一個子view,並且把當前activity給finish掉。
/**
* 回到第一頁(透明頁)
*/
protected void pageOut() {
if (baseHandler == null)
return;
Message localMessage = Message.obtain();
localMessage.what = GOTO_TRANSPARENTVIEW;
baseHandler.sendMessage(localMessage);
}
4. 其中跳轉到viewpager的第一頁、第二頁我們都是通過使用Handler
進行傳遞的。
private Handler baseHandler = new Handler() {
public void handleMessage(Message paramMessage) {
switch (paramMessage.what) {
default:
return;
case GOTO_CONTENTVIEW:
localViewPager.setCurrentItem(views.size() - 1, true);
return;
case GOTO_TRANSPARENTVIEW:
localViewPager.setCurrentItem(0, true);
return;
case FINISH_ACTIVITY:
finish();
return;
}
}
};
//關閉當前頁面
private final static int FINISH_ACTIVITY = 997;
//展示內容view,第二頁
private final static int GOTO_CONTENTVIEW = 998;
//展示第一頁,透明頁面
private final static int GOTO_TRANSPARENTVIEW = 999;
5. 到這裏我們基本完成基本功能。當我們需要實現右滑返回時,只需要繼承我們的SildBaseActivity
並實現我們的
/**
* @return 返回當前頁面展示的view佈局id
*/
public abstract int setContentViewId();
/**
* 初始化view,可以butterknif結合使用
* @param contentView
*/
public abstract void initView(View contentView);
6. 代碼中已經實現了實體返回按鈕的功能所以當我們點擊返回按鈕時,不用擔心出現其他問題
@Override
public boolean onKeyDown(int paramInt, KeyEvent paramKeyEvent) {
if (paramInt == KeyEvent.KEYCODE_BACK) {
pageOut();
return false;
}
return true;
}
@Override
public void onBackPressed() {
super.onBackPressed();
pageOut();
}
7. 該滑動返回是通過viewpager實現,那麼當我們的界面view中也有viewpager的時候,出現了viewpager的嵌套衝突。這個問題已經想到了,所有我們添加了解決衝突的代碼。當有viewpager的時候,只需要在佈局加入以下即可
<com.github.xiaozhucdj.sildbacklibrary.MatchViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
至此viewpager實現簡單右滑返回已經完成,具體代碼已在github開源,有興趣的朋友可以前往查看下載。
本項目github地址:SildBackSample