Android开发之使用150行代码实现滑动返回效果
今天带大家实现滑动返回效果.,具体内容如下所示:
先看看效果图:
因为没有具体内容,也没有简书的图片资源,所以稍微简陋了点.
但是依然不妨碍我们的效果展示~
ok,接下来惯例,通过阅读本文你能学习到:
viewdraghelper的使用(如果你想学习自定义view,那么viewdraghelper你绝对不能错过)
好像也没有什么了....
这个效果,难度不大,会viewdraghelper的同学应该10分钟就能写出来了吧~
如果不会也没关系~
1. 我们自定义一个swipebackframelayout继承自framelayout
1.1 因为看到左边黄色的view是被遮住的,而另外一个view的宽度是matchparent的,所以framelayout是不错的选择.
顺便增加一个回调,通知activity去finish
public void setcallback(callback mcallback){ this.mcallback = mcallback; } private callback mcallback; public interface callback{ void onshouldfinish(); }
1.2 xml布局,非常简单:
<yifeiyuan.practice.practicedemos.drager.swipebackframelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/swipe_back" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="yifeiyuan.practice.practicedemos.drager.swipebackactivity"> <textview android:layout_width="40dp" android:layout_height="match_parent" android:text="@string/hello_world" android:gravity="center" android:background="#ffff00" /> <view android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff00ff" /> </yifeiyuan.practice.practicedemos.drager.swipebackframelayout>
1.3 实例化一个viewdraghelper
//1f代表灵敏度 mdraghelper = viewdraghelper.create(this, 1f,new viewdraghelper.callback() { @override public boolean trycaptureview(view child, int pointerid) { return false; } } //因为我们是从左向右滑动 所以设置edge_left mdraghelper.setedgetrackingenabled(viewdraghelper.edge_left);
1.4 在swipebackframelayout里实例化xml里的子view
private view mdividerview; private view mcontentview; @override protected void onfinishinflate() { super.onfinishinflate(); mdividerview = getchildat(0); mdividerview.setalpha(0f); mcontentview = getchildat(1); }
1.5 让viewdraghelper处理touch事件
@override public boolean onintercepttouchevent(motionevent ev) { return mdraghelper.shouldintercepttouchevent(ev); } @override public boolean ontouchevent(motionevent event) { mdraghelper.processtouchevent(event); return true; }
1.6重写viewdraghelper的一些处理方法
已附上详细注释
@override public void onedgetouched(int edgeflags, int pointerid) { super.onedgetouched(edgeflags, pointerid); //触摸到左边界的时候 我们capture住mcontentview mdraghelper.capturechildview(mcontentview, pointerid); } @override public int getviewhorizontaldragrange(view child) { return 1; } @override public void onviewpositionchanged(view changedview, int left, int top, int dx, int dy) { super.onviewpositionchanged(changedview, left, top, dx, dy); log.d(tag, "onviewpositionchanged() called with left = [" + left + "], top = [" + top + "], dx = [" + dx + "], dy = [" + dy + "]"); //0.0 - 1.0 //notice 这边可以给个接口回调出去,就可以做各种炫酷的效果了 float alpha = (float) (left*1.0/mdividerwidth); mdividerview.setalpha(alpha); } @override public int clampviewpositionhorizontal(view child, int left, int dx) { // log.d(tag, "clampviewpositionhorizontal() called with dx = [" + dx + "]"); // 计算left 我们的目标范围是0-dividerwidth的宽度 mlastdx = dx; int newleft = math.min(mdividerwidth, math.max(left,0)); return newleft; } @override public void onviewreleased(view releasedchild, float xvel, float yvel) { //>0代表用户想关闭 if (mlastdx>0){ // 还不到关闭条件,我们让view滑动过去,再关闭 if (mdividerwidth != releasedchild.getleft()) { mdraghelper.settlecapturedviewat(mdividerwidth,releasedchild.gettop(); invalidate(); } else { if (mcallback != null) { mcallback.onshouldfinish(); } } }else{ //用户不想关闭 ,则滑动到最左边 if (mdividerwidth != 0) { mdraghelper.settlecapturedviewat(0, releasedchild.gettop()); invalidate(); } } } @override public void onviewdragstatechanged(int state) { super.onviewdragstatechanged(state); //滑动停止,并且到达了滑动的判断条件 则回调关闭 if(mdraghelper.getviewdragstate()==viewdraghelper.state_idle&&mcallback != null&&mdividerwidth==mcontentview.getleft()&&mlastdx>0) { mcallback.onshouldfinish(); } } });
1.7 增加对view滑动事件处理,对于以上mdividerwidth我们在onlayout里获取
private int mdividerwidth; @override protected void onlayout(boolean changed, int left, int top, int right, int bottom) { super.onlayout(changed, left, top, right, bottom); mdividerwidth = mdividerview.getwidth(); } //notice view 刚初始化的时候就会被调用一次 @override public void computescroll() { super.computescroll(); // log.d(tag, "computescroll() called with " + ""); if (mdraghelper.continuesettling(true)) { invalidate(); } }
我们写完自定义view后还需要自定义一下activity的退出动画~
2.定义activity的finish动画
2.1 在anim目录下,创建两个动画xml:
//no_anim <alpha android:duration="300" xmlns:android="http://schemas.android.com/apk/res/android" android:fromalpha="1.0" android:toalpha="1.0" ></alpha> //out_to_right <translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300" android:fromxdelta="0%" android:toxdelta="100%" ></translate>
2.2 在activity里设置callback监听,并运用动画
mswipeback.setcallback(new swipebackframelayout.callback() { @override public void onshouldfinish() { finish(); overridependingtransition(r.anim.no_anim, r.anim.out_to_right); } });
好了!!代码量非常少!就是这么简单~
吐槽一下,简书对代码块的支持太差了,代码复制过来全是乱的!!
同学们还是去看源码吧:
源码在我的github上
总结
以上所述是小编给大家介绍的教你150行代码实现滑动返回效果的代码,希望对大家有所帮助