使用SlidingPaneLayout 實現仿微信的滑動返回

来源:https://www.cnblogs.com/wuwenweihe/archive/2018/04/24/8930899.html
-Advertisement-
Play Games

上周,公司的項目改版要求加上一個右滑返回上一個界面,於是就在網上找了一些開源庫打算實現.但是在使用的時候遇見了許多的問題.試了兩天用過 https://github.com/ikew0ng/SwipeBackLayout ,https://github.com/r0adkll/Slidr等庫都沒成功 ...


上周,公司的項目改版要求加上一個右滑返回上一個界面,於是就在網上找了一些開源庫打算實現.但是在使用的時候遇見了許多的問題.試了兩天用過 https://github.com/ikew0ng/SwipeBackLayout ,https://github.com/r0adkll/Slidr等庫都沒成功.

然後在https://www.jianshu.com/p/c0a15bdc2690 看見了使用SlidingPaneLayout 來實現的一個滑動返回案例然後就看了看發現不錯於是就使用了這個.

雖然上面鏈接裡面已近寫好啦.但是還是寫一下代碼:

先看看最終效果:

 

 

 

實現如下:

主要是在baesActivity裡面

public class BaesActivity extends AppCompatActivity implements SlidingPaneLayout.PanelSlideListener{
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        initSlideBackClose();//滑動返回的設置
        super.onCreate(savedInstanceState);
    }

    private void initSlideBackClose() {
        if (isSupportSwipeBack()) {
           SlidingPaneLayout slidingPaneLayout = new SlidingPaneLayout(this);
            // 通過反射改變mOverhangSize的值為0,
            // 這個mOverhangSize值為菜單到右邊屏幕的最短距離,
            // 預設是32dp,現在給它改成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));

            // 左側的透明視圖
            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();


            // 右側的內容視圖
            ViewGroup decorChild = (ViewGroup) decorView.getChildAt(0);
            decorChild.setBackgroundColor(getResources()
                    .getColor(android.R.color.white));
            decorView.removeView(decorChild);
            decorView.addView(slidingPaneLayout);

            // 為 SlidingPaneLayout 添加內容視圖
            slidingPaneLayout.addView(decorChild, 1);
        }
    }
    //設置是否使用滑動返回
    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

看看效果

怎麼會這樣!

然後就去看看那需要改動,發現在BaesActivity裡面寫了一個方法:

  //設置是否使用滑動返回
    protected boolean isSupportSwipeBack() {
        return true;
    }

在不需要返回的界面重寫此方法並返回 false,就行了向這樣

  @Override
    protected boolean isSupportSwipeBack() {
        return false;
    }

 

主界面不滑動的問題解決了,但是還有一個問題在滑動的時候左邊顯示的是一個白板,這怎麼破?

這就要設置  activity 的 style了 在AndroidManifest.xml 文件裡面找到 application 就是黃色那行,跳進去

  <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">//設置樣式
        <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>

設置styles.xml ,添加黃色部分的內容

 <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>
        <!--設置視窗背景為透明-->
        <item name ="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>

運行起來:

偶買噶! 我的首頁怎麼變成這樣了,透明瞭?怎麼辦,

小事,因為我們設置了上面那兩行的原因,現在只要把界面的根佈局裡面添加一個背景色就行了

<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="第一個,下一界面"
        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,初步實現就這樣了,但是這效果也太醜了吧!

嗯,現在來改改Activity的開啟關閉的樣式

還是在styles.xml 進行修改<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>
        <!--設置視窗背景為透明-->
        <item name ="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <!--activity啟動關閉樣式-->
        <item name="android:windowAnimationStyle">@style/activityAnimation</item>
    </style>

<!--activity啟動關閉動畫-->

<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在 

進行設置:

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,效果出來了.但是當它遇到ViewPager的時候呢?

怎麼這樣,ViewPager的右滑無法使用了,SlidingPaneLayout的右滑搶了ViewPager的滑動事件.怎麼辦

然後我就在網上找呀找.終於發現了  https://blog.csdn.net/dota_wy/article/details/52890870 自定義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;
/*
在使用側滑菜單的時候如果主界面中有ViewPager的時候調用該自定義控制項,避免二者的衝突事件的發生
 */
public class PageEnabledSlidingPaneLayout extends SlidingPaneLayout {
    private float mInitialMotionX;
    private float mInitialMotionY;
    private float mEdgeSlop;//手滑動的距離

    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是一個距離
    }

    @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,最終效果就這樣完成了.

感謝 https://blog.csdn.net/dota_wy/article/details/52890870,

感謝 https://www.jianshu.com/p/c0a15bdc2690

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.下載RPM源 直接使用yum命令下載mysql來進行安裝是不能成功的,安裝過程會有問題,這裡需要使用rpm命令來先進下載。下載路徑為: http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm,下載命令如圖: #rpm源參 ...
  • 1. 刪除資料庫或者恢複數據庫時,一定要先將資料庫離線,在執行刪除、恢復操作。 SQL代碼如下: 2. 刪除資料庫用戶時,同樣也要將用戶帳號的進程給關閉,否則會提示:SQLServer無法刪除登錄名'***',因為該用戶當前正處於登錄狀態 SQL代碼如下: 效率上來說,用case 更好一些。不過如果 ...
  • 本文由 網易雲 發佈。 在之前的文章中簡要介紹了Join在大數據領域中的使用背景以及常用的幾種演算法-broadcast hash join 、shuffle hash join以及 sort merge join等,對每一種演算法的核心應用場景也做了相關介紹,這裡再重點說明一番:大表與小表進行join ...
  • 以前,用PhoneGap平臺創建的應用在提交到AppStore中的時候可能會遇到一些問題,不過PhoneGap 0.8.0版本已經很好地解決了這個問題,而且蘋果公司也允許將通過PhoneGap構建的應用發佈到AppStore. 參考資料《iOS編程指南》 ...
  • Android中增加本地程式或者庫,這些程式與其所在路徑沒有關係,只和它們的Android.mk有關係。 Android.mk與普通的makefile略有不同,Android.mk具有統一的寫法,主要包含一些系統的公共的巨集: Android.mk中選項參考以下文件路徑: build/core/con ...
  • 自學安卓也有一年的時間了,與代碼相伴的日子里,苦樂共存。能堅持到現在確實已見到了“往日所未曾見證的風采”。今2018年4月2日,決定用一個案例:Unit_Common,把安卓基礎的知識進行串聯,形成模塊化的總結性測試案例,一方面是對自己的總結,在總結中溫故知新。另一方面通過博客,和眾多開發愛好者進行... ...
  • MainActivity.java activity_main.xml 結果: ...
  • MainActivity.java activity_main.xml 在AndroidManifest添加android.permission.CALL_PHONE許可權 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...