Android中Activity滑動(dòng)關(guān)閉的效果
最近感覺有一個(gè)Activity關(guān)閉的效果挺不錯(cuò)的,就是手勢滑動(dòng)就可以關(guān)閉當(dāng)前Activity,于是就想寫一篇博客和大家一起分享下!廢話不多說,老規(guī)矩,還先上效果圖,更直觀!
項(xiàng)目地址:https://github.com/xinyitiandi/SlidingFinishDemo
上代碼:
1.第一個(gè)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="跳轉(zhuǎn)到第二個(gè)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.第二個(gè)Activity,即要跳轉(zhuǎn)的目標(biāo)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="向右滑動(dòng)關(guān)閉當(dāng)前Activity" android:layout_gravity="center" android:textColor="#000"/> </FrameLayout> </com.ekeguan.slidingfinishdemo.SildingFinishLayout>
注意:這里用到了一個(gè)自定義的布局SildingFinishLayout ,關(guān)于這個(gè)布局的代碼,我一會(huì)在下面貼出,大家不用著急。需要注意的是想要滑動(dòng)關(guān)閉的Activity的布局文件最外層要被SildingFinishLayout 布局包裹,被SildingFinishLayout 包裹的里面的布局設(shè)置背景色,如FrameLayout,我在這里設(shè)置了背景色為“#f0f0f0”,字體要設(shè)置字體顏色,如TextView,我在這里設(shè)置了“#000”
為了達(dá)到理想的效果,在AndroidMainfest.xml文件里面要給想要手勢滑動(dòng)的Activity添加上一個(gè)透明的主題,如:
<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; /** * 自定義可以滑動(dòng)的RelativeLayout, 類似于IOS的滑動(dòng)刪除頁面效果,當(dāng)我們要使用 * 此功能的時(shí)候,需要將該Activity的頂層布局設(shè)置為SildingFinishLayout, * 然后需要調(diào)用setTouchView()方法來設(shè)置需要滑動(dòng)的View * * @author xiaanming * * @blog http://blog.csdn.net/xiaanming * */ public class SildingFinishLayout extends RelativeLayout implements OnTouchListener { /** * SildingFinishLayout布局的父布局 */ private ViewGroup mParentView; /** * 處理滑動(dòng)邏輯的View */ private View touchView; /** * 滑動(dòng)的最小距離 */ private int mTouchSlop; /** * 按下點(diǎn)的X坐標(biāo) */ private int downX; /** * 按下點(diǎn)的Y坐標(biāo) */ private int downY; /** * 臨時(shí)存儲(chǔ)X坐標(biāo) */ private int tempX; /** * 滑動(dòng)類 */ private Scroller mScroller; /** * SildingFinishLayout的寬度 */ private int viewWidth; /** * 記錄是否正在滑動(dòng) */ 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(); } } /** * 設(shè)置OnSildingFinishListener, 在onSildingFinish()方法中finish Activity * * @param onSildingFinishListener */ public void setOnSildingFinishListener( OnSildingFinishListener onSildingFinishListener) { this.onSildingFinishListener = onSildingFinishListener; } /** * 設(shè)置Touch的View * * @param touchView */ public void setTouchView(View touchView) { this.touchView = touchView; touchView.setOnTouchListener(this); } public View getTouchView() { return touchView; } /** * 滾動(dòng)出界面 */ private void scrollRight() { final int delta = (viewWidth + mParentView.getScrollX()); // 調(diào)用startScroll方法來設(shè)置一些滾動(dòng)的參數(shù),我們在computeScroll()方法中調(diào)用scrollTo來滾動(dòng)item mScroller.startScroll(mParentView.getScrollX(), 0, -delta + 1, 0, Math.abs(delta)); postInvalidate(); } /** * 滾動(dòng)到起始位置 */ 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, // 則當(dāng)手指滑動(dòng),取消item的點(diǎn)擊事件,不然我們滑動(dòng)也伴隨著item點(diǎn)擊事件的發(fā)生 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); // 屏蔽在滑動(dòng)過程中ListView ScrollView等自己的滑動(dòng)事件 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() { // 調(diào)用startScroll的時(shí)候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(); } }
最后項(xiàng)目地址:https://github.com/xinyitiandi/SlidingFinishDemo
以上所述是小編給大家介紹的Android中Activity滑動(dòng)關(guān)閉的效果,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
Android中EditText屏蔽第三方輸入法表情的方法示例
最近在工作終于遇到一個(gè)問題,因?yàn)榈谌捷斎敕ū砬榈膯栴}導(dǎo)致Android中TextView的內(nèi)容顯示異常,只能想辦法解決了,下面這篇文章主要記錄了在處理Android中EditText屏蔽第三方輸入法表情的方法,需要的朋友可以參考借鑒,下面來一起看看吧。2017-01-01android打開應(yīng)用所在的市場頁面進(jìn)行評分操作的方法
這篇文章主要介紹了android打開應(yīng)用所在的市場頁面進(jìn)行評分操作的方法,涉及Android操作市場頁面評分效果的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04Android 優(yōu)化之a(chǎn)pp啟動(dòng)優(yōu)化的實(shí)現(xiàn)
這篇文章主要介紹了Android 優(yōu)化之啟動(dòng)優(yōu)化的實(shí)現(xiàn),啟動(dòng)分為冷啟動(dòng)和熱啟動(dòng),溫啟動(dòng),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07Android簡單實(shí)現(xiàn)自定義流式布局的方法
這篇文章主要介紹了Android簡單實(shí)現(xiàn)自定義流式布局的方法,結(jié)合實(shí)例形式分析了Android流式布局的原理與實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-07-07Android RecyclerView顯示Item布局不一致解決辦法
這篇文章主要介紹了Android RecyclerView顯示Item布局不一致解決辦法的相關(guān)資料,需要的朋友可以參考下2017-07-07