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

Android中Activity滑动关闭的效果

程序员文章站 2023-11-29 16:50:58
最近感觉有一个activity关闭的效果挺不错的,就是手势滑动就可以关闭当前activity,于是就想写一篇博客和大家一起分享下!废话不多说,老规矩,还先上效果图,更直观!...

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

Android中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滑动关闭的效果,希望对大家有所帮助