Activity滑动关闭的效果

来源:互联网 发布:同花顺开户软件 编辑:程序博客网 时间:2024/05/17 08:36

最近感觉有一个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

0 0
原创粉丝点击