天天看點

android 側滑菜單_Android 常用側滑欄實作

我們在平常使用手機時可以看到很多的App的會有側滑菜單欄的效果,這次我将使用SlidingPaneLayout來實作這個功能。

首先我們先看下最終效果:

android 側滑菜單_Android 常用側滑欄實作

SlidingPaneLayout

SlidingPaneLayout提供了一個水準的、多窗格的布局。使用該控件我們可以實作側滑的效果,其布局檔案下面的第一個子控件是作為一個導航視圖(也就是滑動後左邊視圖),其餘部分是内容視圖。

可以簡單的嘗試一下

<?xml version="1.0" encoding="utf-8"?> <androidx.slidingpanelayout.widget.SlidingPaneLayout 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:gravity="center_horizontal"     tools:context=".MainActivity">      <LinearLayout         android:layout_width="150dp"         android:layout_height="match_parent"         android:background="@color/colorPrimary"         android:orientation="vertical">          <TextView             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:text="LeftMenu"             android:textSize="20sp"             android:layout_margin="10dp"/>     LinearLayout>      <LinearLayout         android:layout_width="match_parent"         android:layout_height="match_parent"         android:gravity="center"         android:orientation="vertical">          <TextView             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:text="main"             android:textSize="30sp"             android:layout_margin="10dp"/>     LinearLayout>   androidx.slidingpanelayout.widget.SlidingPaneLayout>
           

通過上面的布局,我們可以實作一個測滑的效果

android 側滑菜單_Android 常用側滑欄實作

左側欄縮放

通過下面這段代碼,使得左側欄滑動時有一個縮放的效果

SlidingPaneLayout slidingPaneLayout = findViewById(R.id.sliding_layout);  //擷取到左側導航欄 mLeftView = slidingPaneLayout.getChildAt(0); slidingPaneLayout.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {     @Override     public void onPanelSlide(@NonNull View panel, float slideOffset) {         //滑動窗格的位置更改時調用         //設定側面欄縮放         mLeftView.setPivotX(-mLeftView.getWidth() / 6.0f);         mLeftView.setPivotY(mLeftView.getHeight() / 2.0f);         mLeftView.setScaleX(0.7f + 0.3f * slideOffset);         mLeftView.setScaleY(0.7f + 0.3f * slideOffset);     }     @Override     public void onPanelOpened(@NonNull View panel) {         //在滑動窗格完全打開時調用     }     @Override     public void onPanelClosed(@NonNull View panel) {         //當滑動窗格完全關閉時調用     } }); mLeftView = slidingPaneLayout.getChildAt(0); slidingPaneLayout.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() {     @Override     public void onPanelSlide(@NonNull View panel, float slideOffset) {         //滑動窗格的位置更改時調用         //設定側面欄縮放         mLeftView.setPivotX(-mLeftView.getWidth() / 6.0f);         mLeftView.setPivotY(mLeftView.getHeight() / 2.0f);         mLeftView.setScaleX(0.7f + 0.3f * slideOffset);         mLeftView.setScaleY(0.7f + 0.3f * slideOffset);     }     @Override     public void onPanelOpened(@NonNull View panel) {         //在滑動窗格完全打開時調用     }     @Override     public void onPanelClosed(@NonNull View panel) {         //當滑動窗格完全關閉時調用     } });
           

在onPaneSlide中有兩個參數,第一個參數是被移動的view,第二個參數則是滑動時的偏移值,範圍是0~1

當我們對一個View設定縮放動畫時,縮放軸點預設是該View的中心點。如果我們想改變縮放軸點位置,可以通過setPivotX(float pivotX)設定縮放軸點X軸的坐标,通過setPivotY(float pivotY)設定縮放軸點Y軸的坐标。再通過setScaleX和setScaleY來實作最終的縮放效果。

實作效果:

android 側滑菜單_Android 常用側滑欄實作

在SlidingPaneLayout下添加個背景顔色效果會更好些

android:background="@color/colorPrimary"
           
android 側滑菜單_Android 常用側滑欄實作

主要内容(右側)縮放

在onPanelSlide方法下加上下面一段代碼,即可實作

mMainView.setScaleX(1f - 0.3f * slideOffset); mMainView.setScaleY(1f - 0.3f * slideOffset);
           
android 側滑菜單_Android 常用側滑欄實作

還可以再給右邊設定個陰影的效果

mMainView.setElevation(6.0f * slideOffset);
           

自定義SlidingPaneLayout

上面就是最終要實作的側滑欄的三個最主要的内容。了解上面三個其實就可以做出一開始給的那種效果。但有些時候,可能我們不希望通過滑動來顯示出左邊的導航欄,而是直接通過點選一個按鈕來打開左邊欄。在SlidingPaneLayout中并沒這樣的方法來禁止它滑動,這時候我們就需要自己來自定義。

public class CusSlidingPaneLayout extends SlidingPaneLayout {     //是否禁止     private boolean isForbid = false;      public CusSlidingPaneLayout(@NonNull Context context) {         this(context, null);     }      public CusSlidingPaneLayout(@NonNull Context context, @Nullable AttributeSet attrs) {         this(context, attrs, 0);     }      public CusSlidingPaneLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {         super(context, attrs, defStyle);     }      /**      * 讓外面可以調用此方法來禁止滑動      *      * @param isForbid      */     public void forbidSlide(boolean isForbid) {         this.isForbid = isForbid;     }      /**      * 攔截觸屏事件      *      * @param ev      * @return      */     @Override     public boolean onInterceptTouchEvent(MotionEvent ev) {         if (ev.getAction() == MotionEvent.ACTION_MOVE) {             if (isForbid) {                 return false;             }         }         return super.onInterceptTouchEvent(ev);     }      @Override     public boolean onTouchEvent(MotionEvent ev) {         if (ev.getAction() == MotionEvent.ACTION_MOVE) {             if (isForbid) {                 return false;             }         }         return super.onTouchEvent(ev);     } }
           

Demo位址

https://github.com/barry-b/SlideMenuDemo