不得不说现在技术迭代的非常快,之前很牛逼的想法、点子,现在觉得已经很槽糠了。
右滑返回在很多新项目中陆陆续续都加上了。该技术最早是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