欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发之使用150行代码实现滑动返回效果

程序员文章站 2023-12-02 08:56:34
今天带大家实现滑动返回效果.,具体内容如下所示: 先看看效果图: 因为没有具体内容,也没有简书的图片资源,所以稍微简陋了点. 但是依然不妨碍我们的效果展示~...

今天带大家实现滑动返回效果.,具体内容如下所示:

先看看效果图:

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行代码实现滑动返回效果的代码,希望对大家有所帮助