当前位置: 移动技术网 > 移动技术>移动开发>Android > Android中Activity滑动关闭的效果

Android中Activity滑动关闭的效果

2019年07月24日  | 移动技术网移动技术  | 我要评论

最近感觉有一个activity关闭的效果挺不错的,就是手势滑动就可以关闭当前activity,于是就想写一篇博客和大家一起分享下!废话不多说,老规矩,还先上效果图,更直观!

这里写图片描述

项目地址:https://github.com/xinyitiandi/slidingfinishdemo

上代码:

1.第一个activity:

package com.ekeguan.slidingfinishdemo;
import android.content.intent;
import android.os.bundle;
import android.support.v7.app.appcompatactivity;
import android.view.view;
import android.widget.button;
public class mainactivity extends appcompatactivity implements view.onclicklistener {
 private button button;
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
  initview();
  initeventlistener();
 }
 private void initview() {
  button = (button) findviewbyid(r.id.button);
 }
 private void initeventlistener() {
  button.setonclicklistener(this);
 }
 @override
 public void onclick(view view) {
  switch(view.getid())
  {
   case r.id.button:
    startactivity(new intent(mainactivity.this,secondactivity.class));
    break;
   default:
    break;
  }
 }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context="com.ekeguan.slidingfinishdemo.mainactivity">
 <button
  android:id="@+id/button"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="跳转到第二个activity"
  app:layout_constraintbottom_tobottomof="parent"
  app:layout_constraintleft_toleftof="parent"
  app:layout_constraintright_torightof="parent"
  app:layout_constrainttop_totopof="parent" />
</android.support.constraint.constraintlayout>

2.第二个activity,即要跳转的目标activity

package com.ekeguan.slidingfinishdemo;
import android.os.bundle;
import android.support.v7.app.appcompatactivity;
public class secondactivity extends appcompatactivity {
 private sildingfinishlayout msildingfinishlayout;
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_second);
  initview();
  initeventlistener();
 }
 private void initview() {
  msildingfinishlayout = (sildingfinishlayout) findviewbyid(r.id.sildingfinishlayout);
  msildingfinishlayout.settouchview(msildingfinishlayout);
 }
 private void initeventlistener() {
  msildingfinishlayout
    .setonsildingfinishlistener(new sildingfinishlayout.onsildingfinishlistener() {
     @override
     public void onsildingfinish() {
      finish();
     }
    });
 }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<com.ekeguan.slidingfinishdemo.sildingfinishlayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/sildingfinishlayout"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:gravity="center">
 <framelayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="#f0f0f0">
  <textview
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="向右滑动关闭当前activity"
   android:layout_gravity="center"
   android:textcolor="#000"/>
 </framelayout>
</com.ekeguan.slidingfinishdemo.sildingfinishlayout>

注意:这里用到了一个自定义的布局sildingfinishlayout ,关于这个布局的代码,我一会在下面贴出,大家不用着急。需要注意的是想要滑动关闭的activity的布局文件最外层要被sildingfinishlayout 布局包裹,被sildingfinishlayout 包裹的里面的布局设置背景色,如framelayout,我在这里设置了背景色为“#f0f0f0”,字体要设置字体颜色,如textview,我在这里设置了“#000”

为了达到理想的效果,在androidmainfest.xml文件里面要给想要手势滑动的activity添加上一个透明的主题,如:

<activity android:name=".secondactivity"
   android:screenorientation="portrait"
   android:theme="@style/theme.appcompat.translucent"></activity>

主题:

<style name="theme.appcompat.translucent">
  <item name="android:windowbackground">@android:color/transparent</item>
  <item name="android:colorbackgroundcachehint">@null</item>
  <item name="android:windowistranslucent">true</item>
  <item name="windowactionbar">false</item>
  <item name="windownotitle">true</item>
 </style>

好了,到这里差不多了,下面贴上自定义布局sildingfinishlayout的代码:

package com.ekeguan.slidingfinishdemo;
import android.content.context;
import android.util.attributeset;
import android.view.motionevent;
import android.view.view;
import android.view.view.ontouchlistener;
import android.view.viewconfiguration;
import android.view.viewgroup;
import android.widget.abslistview;
import android.widget.relativelayout;
import android.widget.scrollview;
import android.widget.scroller;
/**
 * 自定义可以滑动的relativelayout, 类似于ios的滑动删除页面效果,当我们要使用
 * 此功能的时候,需要将该activity的顶层布局设置为sildingfinishlayout,
 * 然后需要调用settouchview()方法来设置需要滑动的view
 *
 * @author xiaanming
 *
 * @blog http://blog.csdn.net/xiaanming
 *
 */
public class sildingfinishlayout extends relativelayout implements
  ontouchlistener {
 /**
  * sildingfinishlayout布局的父布局
  */
 private viewgroup mparentview;
 /**
  * 处理滑动逻辑的view
  */
 private view touchview;
 /**
  * 滑动的最小距离
  */
 private int mtouchslop;
 /**
  * 按下点的x坐标
  */
 private int downx;
 /**
  * 按下点的y坐标
  */
 private int downy;
 /**
  * 临时存储x坐标
  */
 private int tempx;
 /**
  * 滑动类
  */
 private scroller mscroller;
 /**
  * sildingfinishlayout的宽度
  */
 private int viewwidth;
 /**
  * 记录是否正在滑动
  */
 private boolean issilding;
 private onsildingfinishlistener onsildingfinishlistener;
 private boolean isfinish;
 public sildingfinishlayout(context context, attributeset attrs) {
  this(context, attrs, 0);
 }
 public sildingfinishlayout(context context, attributeset attrs, int defstyle) {
  super(context, attrs, defstyle);
  mtouchslop = viewconfiguration.get(context).getscaledtouchslop();
  mscroller = new scroller(context);
 }
 @override
 protected void onlayout(boolean changed, int l, int t, int r, int b) {
  super.onlayout(changed, l, t, r, b);
  if (changed) {
   // 获取sildingfinishlayout所在布局的父布局
   mparentview = (viewgroup) this.getparent();
   viewwidth = this.getwidth();
  }
 }
 /**
  * 设置onsildingfinishlistener, 在onsildingfinish()方法中finish activity
  *
  * @param onsildingfinishlistener
  */
 public void setonsildingfinishlistener(
   onsildingfinishlistener onsildingfinishlistener) {
  this.onsildingfinishlistener = onsildingfinishlistener;
 }
 /**
  * 设置touch的view
  *
  * @param touchview
  */
 public void settouchview(view touchview) {
  this.touchview = touchview;
  touchview.setontouchlistener(this);
 }
 public view gettouchview() {
  return touchview;
 }
 /**
  * 滚动出界面
  */
 private void scrollright() {
  final int delta = (viewwidth + mparentview.getscrollx());
  // 调用startscroll方法来设置一些滚动的参数,我们在computescroll()方法中调用scrollto来滚动item
  mscroller.startscroll(mparentview.getscrollx(), 0, -delta + 1, 0,
    math.abs(delta));
  postinvalidate();
 }
 /**
  * 滚动到起始位置
  */
 private void scrollorigin() {
  int delta = mparentview.getscrollx();
  mscroller.startscroll(mparentview.getscrollx(), 0, -delta, 0,
    math.abs(delta));
  postinvalidate();
 }
 /**
  * touch的view是否是abslistview, 例如listview, gridview等其子类
  *
  * @return
  */
 private boolean istouchonabslistview() {
  return touchview instanceof abslistview ? true : false;
 }
 /**
  * touch的view是否是scrollview或者其子类
  *
  * @return
  */
 private boolean istouchonscrollview() {
  return touchview instanceof scrollview ? true : false;
 }
 @override
 public boolean ontouch(view v, motionevent event) {
  switch (event.getaction()) {
   case motionevent.action_down:
    downx = tempx = (int) event.getrawx();
    downy = (int) event.getrawy();
    break;
   case motionevent.action_move:
    int movex = (int) event.getrawx();
    int deltax = tempx - movex;
    tempx = movex;
    if (math.abs(movex - downx) > mtouchslop
      && math.abs((int) event.getrawy() - downy) < mtouchslop) {
     issilding = true;
     // 若touchview是abslistview,
     // 则当手指滑动,取消item的点击事件,不然我们滑动也伴随着item点击事件的发生
     if (istouchonabslistview()) {
      motionevent cancelevent = motionevent.obtain(event);
      cancelevent
        .setaction(motionevent.action_cancel
          | (event.getactionindex() << motionevent.action_pointer_index_shift));
      v.ontouchevent(cancelevent);
     }
    }
    if (movex - downx >= 0 && issilding) {
     mparentview.scrollby(deltax, 0);
     // 屏蔽在滑动过程中listview scrollview等自己的滑动事件
     if (istouchonscrollview() || istouchonabslistview()) {
      return true;
     }
    }
    break;
   case motionevent.action_up:
    issilding = false;
    if (mparentview.getscrollx() <= -viewwidth / 2) {
     isfinish = true;
     scrollright();
    } else {
     scrollorigin();
     isfinish = false;
    }
    break;
  }
  // 假如touch的view是abslistview或者scrollview 我们处理完上面自己的逻辑之后
  // 再交给abslistview, scrollview自己处理其自己的逻辑
  if (istouchonscrollview() || istouchonabslistview()) {
   return v.ontouchevent(event);
  }
  // 其他的情况直接返回true
  return true;
 }
 @override
 public void computescroll() {
  // 调用startscroll的时候scroller.computescrolloffset()返回true,
  if (mscroller.computescrolloffset()) {
   mparentview.scrollto(mscroller.getcurrx(), mscroller.getcurry());
   postinvalidate();
   if (mscroller.isfinished()) {
    if (onsildingfinishlistener != null && isfinish) {
     onsildingfinishlistener.onsildingfinish();
    }
   }
  }
 }
 public interface onsildingfinishlistener {
  public void onsildingfinish();
 }
}

最后项目地址:https://github.com/xinyitiandi/slidingfinishdemo

以上所述是小编给大家介绍的android中activity滑动关闭的效果,希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网