Android使用SlidingPaneLayout 實(shí)現(xiàn)仿微信的滑動(dòng)返回
上周,公司的項(xiàng)目改版要求加上一個(gè)右滑返回上一個(gè)界面,于是就在網(wǎng)上找了一些開源庫打算實(shí)現(xiàn).但是在使用的時(shí)候遇見了許多的問題.試了兩天用過 https://github.com/ikew0ng/SwipeBackLayout , https://github.com/r0adkll/Slidr 等庫都沒成功.
然后在http://www.dbjr.com.cn/article/138869.htm看見了使用SlidingPaneLayout 來實(shí)現(xiàn)的一個(gè)滑動(dòng)返回案例然后就看了看發(fā)現(xiàn)不錯(cuò)于是就使用了這個(gè).
雖然上面鏈接里面已近寫好啦.但是還是寫一下代碼:
先看看最終效果:
實(shí)現(xiàn)如下:
主要是在baesActivity里面
public class BaesActivity extends AppCompatActivity implements SlidingPaneLayout.PanelSlideListener{ @Override protected void onCreate(@Nullable Bundle savedInstanceState) { initSlideBackClose();//滑動(dòng)返回的設(shè)置 super.onCreate(savedInstanceState); } private void initSlideBackClose() { if (isSupportSwipeBack()) { SlidingPaneLayout slidingPaneLayout = new SlidingPaneLayout(this); // 通過反射改變mOverhangSize的值為0, // 這個(gè)mOverhangSize值為菜單到右邊屏幕的最短距離, // 默認(rèn)是32dp,現(xiàn)在給它改成0 try { Field overhangSize = SlidingPaneLayout.class.getDeclaredField("mOverhangSize"); overhangSize.setAccessible(true); overhangSize.set(slidingPaneLayout, 0); } catch (Exception e) { e.printStackTrace(); } slidingPaneLayout.setPanelSlideListener(this); slidingPaneLayout.setSliderFadeColor(getResources() .getColor(android.R.color.transparent)); // 左側(cè)的透明視圖 View leftView = new View(this); leftView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); slidingPaneLayout.addView(leftView, 0); ViewGroup decorView = (ViewGroup) getWindow().getDecorView(); // 右側(cè)的內(nèi)容視圖 ViewGroup decorChild = (ViewGroup) decorView.getChildAt(0); decorChild.setBackgroundColor(getResources() .getColor(android.R.color.white)); decorView.removeView(decorChild); decorView.addView(slidingPaneLayout); // 為 SlidingPaneLayout 添加內(nèi)容視圖 slidingPaneLayout.addView(decorChild, 1); } } //設(shè)置是否使用滑動(dòng)返回 protected boolean isSupportSwipeBack() { return true; } @Override public void onPanelSlide(View panel, float slideOffset) { } @Override public void onPanelOpened(View panel) { finish(); } @Override public void onPanelClosed(View panel) { } }
然后讓Acitivity繼承baesActivity就可以了
public class MainActivity extends BaesActivity
看看效果
怎么會(huì)這樣!
然后就去看看那需要改動(dòng),發(fā)現(xiàn)在BaesActivity里面寫了一個(gè)方法:
//設(shè)置是否使用滑動(dòng)返回 protected boolean isSupportSwipeBack() { return true; }
在不需要返回的界面重寫此方法并返回 false,就行了向這樣
@Override protected boolean isSupportSwipeBack() { return false; }
主界面不滑動(dòng)的問題解決了,但是還有一個(gè)問題在滑動(dòng)的時(shí)候左邊顯示的是一個(gè)白板,這怎么破?
這就要設(shè)置 activity 的 style了 在AndroidManifest.xml 文件里面找到 application 就是黃色那行,跳進(jìn)去
<application android:name=".MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">//設(shè)置樣式 <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".TwoActivity"/> <activity android:name=".ThreeActivity"/> </application>
設(shè)置styles.xml ,添加黃色部分的內(nèi)容
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <!--設(shè)置窗口背景為透明--> <item name ="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@android:color/transparent</item> </style>
運(yùn)行起來:
偶買噶! 我的首頁怎么變成這樣了,透明了?怎么辦,
小事,因?yàn)槲覀冊(cè)O(shè)置了上面那兩行的原因,現(xiàn)在只要把界面的根布局里面添加一個(gè)背景色就行了
<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" android:orientation="vertical" android:background="#f2f2f2" tools:context="com.mvp.tl.myslidingpanelayoutdemo.MainActivity"> <Button android:id="@+id/next" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="第一個(gè),下一界面" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
OK,初步實(shí)現(xiàn)就這樣了,但是這效果也太丑了吧!
嗯,現(xiàn)在來改改Activity的開啟關(guān)閉的樣式
還是在styles.xml 進(jìn)行修改<resources>
<!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <!--設(shè)置窗口背景為透明--> <item name ="android:windowIsTranslucent">true</item> <item name="android:windowBackground">@android:color/transparent</item> <!--activity啟動(dòng)關(guān)閉樣式--> <item name="android:windowAnimationStyle">@style/activityAnimation</item> </style> <!--activity啟動(dòng)關(guān)閉動(dòng)畫--> <style name="activityAnimation" parent="@android:style/Animation"> <item name="android:activityOpenEnterAnimation">@anim/in_from_right</item> <item name="android:activityCloseExitAnimation">@anim/out_to_left</item> </style>
anim/in_from_right.xml和anim/out_to_left在
進(jìn)行設(shè)置:
in_from_right.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fillAfter="true" android:fromXDelta="100%p" android:interpolator="@android:anim/accelerate_interpolator" android:toXDelta="0" /> </set>
out_to_left.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fillAfter="true" android:fromXDelta="0" android:interpolator="@android:anim/accelerate_interpolator" android:toXDelta="100%p" /> </set>
然后看看效果
OK,效果出來了.但是當(dāng)它遇到ViewPager的時(shí)候呢?
怎么這樣,ViewPager的右滑無法使用了,SlidingPaneLayout的右滑搶了ViewPager的滑動(dòng)事件.怎么辦
自定義SlidingPaneLayout
import android.content.Context; import android.support.v4.view.MotionEventCompat; import android.support.v4.widget.SlidingPaneLayout; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.ViewConfiguration; /* 在使用側(cè)滑菜單的時(shí)候如果主界面中有ViewPager的時(shí)候調(diào)用該自定義控件,避免二者的沖突事件的發(fā)生 */ public class PageEnabledSlidingPaneLayout extends SlidingPaneLayout { private float mInitialMotionX; private float mInitialMotionY; private float mEdgeSlop;//手滑動(dòng)的距離 public PageEnabledSlidingPaneLayout(Context context) { this(context, null); } public PageEnabledSlidingPaneLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public PageEnabledSlidingPaneLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); ViewConfiguration config = ViewConfiguration.get(context); mEdgeSlop = config.getScaledEdgeSlop();//getScaledTouchSlop是一個(gè)距離 } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (MotionEventCompat.getActionMasked(ev)) { case MotionEvent.ACTION_DOWN: { mInitialMotionX = ev.getX(); mInitialMotionY = ev.getY(); break; } case MotionEvent.ACTION_MOVE: { final float x = ev.getX(); final float y = ev.getY(); // The user should always be able to "close" the pane, so we only check // for child scrollability if the pane is currently closed. if (mInitialMotionX > mEdgeSlop && !isOpen() && canScroll(this, false, Math.round(x - mInitialMotionX), Math.round(x), Math.round(y))) { // How do we set super.mIsUnableToDrag = true? // send the parent a cancel event MotionEvent cancelEvent = MotionEvent.obtain(ev); cancelEvent.setAction(MotionEvent.ACTION_CANCEL); return super.onInterceptTouchEvent(cancelEvent); } } } return super.onInterceptTouchEvent(ev); } }
并用其替換BaesActivity 里面的SlidingPaneLayout 就可以了
OK,最終效果就這樣完成了.
總結(jié)
以上所述是小編給大家介紹的Android使用SlidingPaneLayout 實(shí)現(xiàn)仿微信的滑動(dòng)返回效果,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Android設(shè)計(jì)模式之代理模式Proxy淺顯易懂的詳細(xì)說明
Android設(shè)計(jì)模式之代理模式也是平時(shí)比較常用的設(shè)計(jì)模式之一,代理模式其實(shí)就是提供了一個(gè)新的對(duì)象,實(shí)現(xiàn)了對(duì)真實(shí)對(duì)象的操作,或成為真實(shí)對(duì)象的替身2018-03-03Android Notification的多種用法總結(jié)
這篇文章主要介紹了Android Notification的多種用法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-06-06Android中快速便捷的實(shí)現(xiàn)圓角按鈕方法詳解
圓角按鈕在我們現(xiàn)在的界面中常常會(huì)用到,最近在開發(fā)中就又遇到了,所以想著有沒有更快速更便捷的實(shí)現(xiàn)方法呢,所以就有了這篇文章,本文主要給大家介紹了關(guān)于Android中如何快速便捷的實(shí)現(xiàn)圓角按鈕的相關(guān)資料,需要的朋友可以參考下。2017-05-05Android學(xué)習(xí)筆記——Menu介紹(三)
今天繼續(xù)昨天沒有講完的Menu的學(xué)習(xí),主要是Popup Menu的學(xué)習(xí),需要的朋友可以參考下2014-10-10