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