鴻蒙開源第三方組件——SlidingMenu_ohos側滑菜單組件


目錄:

1、前言

2、背景

3、效果展示

4、Sample解析

5、Library解析

6、《鴻蒙開源第三方組件》文章合集

前言

          基於安卓平台的SlidingMenu側滑菜單組件(https://github.com/jfeinstein10/SlidingMenu),實現了鴻蒙化遷移和重構,代碼已經開源到(https://gitee.com/isrc_ohos/sliding-menu_ohos),歡迎各位下載使用並提出寶貴意見!

背景

          SlidingMenu_ohos提供了一個側滑菜單的導航框架,使菜單可以隱藏在手機屏幕的左側、右側或左右兩側。當用戶使用時,通過左滑或者右滑的方式調出,既節省了主屏幕的空間,也方便用戶操作,在很多主流APP中都有廣泛的應用。

效果展示

        由於菜單從左右兩側調出的顯示效果相似,此處僅以菜單從左側調出為例進行效果展示。

       組件未啟用時,應用顯示主頁面。單指觸摸屏幕左側並逐漸向右滑動,菜單頁面逐漸顯示,主頁面逐漸隱藏。向右滑動的距離超過某個閾值時,菜單頁面全部顯示,效果如圖1所示。

鴻蒙開源第三方組件——SlidingMenu_ohos側滑菜單組件

圖1 菜單展示和隱藏效果圖

Sample解析

        Sample部分的內容較為簡單,主要包含兩個部分。一是創建SlidingMenu_ohos組件的對象,可根據用戶的實際需求,調用Library的接口,對組件的具體屬性進行設置。二是將設置好的組件添加到Ability中。下面將詳細介紹組件的使用方法。

1、導入SlidingMenu類

import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; 

2、設置Ability的布局

     此布局用作為主頁面的布局,在組件隱藏的時候顯示。

DirectionalLayout directionalLayout = (DirectionalLayout)LayoutScatter.getInstance(this).parse(ResourceTable.Layout_activity_main,null,false);setUIContent(directionalLayout); 

 

3、實例化組件的對象

SlidingMenu slidingMenu = null; try { //初始化SlidingMenu實例 slidingMenu = new SlidingMenu(this); } catch (IOException e) { e.printStackTrace(); } catch (NotExistException e) { e.printStackTrace(); } 

4、設置組件屬性

       此步驟可以根據具體需求,設置組件的位置、觸發范圍、布局、最大寬度等屬性。

//設置菜單放置位置 slidingMenu.setMode(SlidingMenu.LEFT); //設置組件的觸發范圍 slidingMenu.setTouchScale(100); //設置組件的布局 slidingMenu.setMenu(ResourceTable.Layout_layout_left_menu); //設置菜單最大寬度 slidingMenu.setMenuWidth(800); 

5、關聯Ability

        attachToAbility()方法是Library提供的重要方法,用於將菜單組件關聯到Ability。其參數SLIDING_WINDOW和SLIDING_CONTENT是菜單的不同模式,SLIDING_WINDOW模式下的菜單包含Title / ActionBar部分,菜單需在整個手機頁面上顯示,如圖2所示;SLIDING_CONTENT模式下的菜單不包括包含Title / ActionBar部分,菜單可以在手機頁面的局部范圍內顯示,如圖3所示。

try { //關聯Ability,獲取頁面展示根節點 slidingMenu.attachToAbility(directionalLayout,this, SlidingMenu.SLIDING_WINDOW); } catch (NotExistException e) { e.printStackTrace(); } catch (WrongTypeException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } 

 

鴻蒙開源第三方組件——SlidingMenu_ohos側滑菜單組件

 圖2 SLIDING_WINDOW展示效果圖

鴻蒙開源第三方組件——SlidingMenu_ohos側滑菜單組件

圖3  SLIDING_CONTENT展示效果圖

Library解析

        Library的工程結構如下圖所示,CustomViewAbove表示主頁面,CustomViewBehind表示菜單頁面,SlidingMenu主要用於控制主頁面位於菜單頁面的上方,還可以設置菜單的寬度、觸發范圍、顯示模式等屬性。為了方便解釋,以下均以手指從左側觸摸屏幕並向右滑動為例進行講解,菜單均采用SLIDING_WINDOW的顯示模式。

鴻蒙開源第三方組件——SlidingMenu_ohos側滑菜單組件

圖4  Library的工程結構

1、CustomViewAbove主頁面

        CustomViewAbove需要監聽觸摸、移動、抬起和取消等Touch事件,並記錄手指滑動的距離和速度。

      (1)對Touch事件的處理

        Touch事件決定了菜單的顯示、移動和隱藏。例如:在菜單的觸發范圍內,手指向右滑動(POINT_MOVE)時,菜單會跟隨滑動到手指所在位置。手指抬起(PRIMARY_POINT_UP)或者取消滑動(CANCEL)時,會依據手指滑動的距離和速度決定菜單頁面的下一狀態是全部隱藏還是全部顯示。

 switch (action) { //按下 case TouchEvent.PRIMARY_POINT_DOWN: ..... mInitialMotionX=mLastMotionX=ev.getPointerPosition(mActivePointerId).getX(); break; //滑動 case TouchEvent.POINT_MOVE: ...... //菜單滑動到此時手指所在位置(x) left_scrollto(x); break; //抬起 case TouchEvent.PRIMARY_POINT_UP: ...... //獲得菜單的下一狀態(全屏顯示或者全部隱藏) int nextPage = determineTargetPage(pageOffset, initialVelocity,totalDelta); //設置菜單的下一狀態 setCurrentItemInternal(nextPage,initialVelocity); ...... endDrag(); break; //取消 case TouchEvent.CANCEL: ...... //根據菜單當前狀態mCurItem設置菜單下一狀態 setCurrentItemInternal(mCurItem); //結束拖動 endDrag(); break; }

 

      (2)對滑動的距離和速度的處理

        手指抬起時,滑動的速度和距離分別大於最小滑動速度和最小移動距離,判定此時的操作為快速拖動,菜單立即彈出並全部顯示,如圖5所示。

private int determineTargetPage(float pageOffset, int velocity, int deltaX) { //獲得當前菜單狀態,0:左側菜單正在展示,1:菜單隱藏,2:右側菜單正在展示 int targetPage = getCurrentItem(); //針對快速拖動的判斷 if (Math.abs(deltaX) > mFlingDistance && Math.abs(velocity) > mMinimumVelocity) { if (velocity > 0 && deltaX > 0) { targetPage -= 1; } else if (velocity < 0 && deltaX < 0){ targetPage += 1; } } } 

 

鴻蒙開源第三方組件——SlidingMenu_ohos側滑菜單組件

圖5  快速拖動效果圖

        當手指抬起並且不滿足快速拖動標准時,需要根據滑動距離判斷菜單的隱藏或顯示。若菜單已展開的部分超過自身寬度的1/2,菜單立即彈出全部顯示,,效果圖如圖1所示;若不足自身寬度的1/2,則立即彈回全部隱藏,效果圖如圖6所示。

//獲得當前菜單狀態,0:左側菜單正在展示,1:菜單隱藏,2:右側菜單正在展示 switch (mCurItem){ case 0: targetPage=1-Math.round(pageOffset); break; case 1: //菜單隱藏時,首先要判斷此時菜單的放置狀態是左側還是右側 if(current_state == SlidingMenu.LEFT){ targetPage = Math.round(1-pageOffset); } if(current_state == SlidingMenu.RIGHT){ targetPage = Math.round(1+pageOffset); } break; case 2: targetPage = Math.round(1+pageOffset); break; }

 

鴻蒙開源第三方組件——SlidingMenu_ohos側滑菜單組件 

圖6 緩慢拖動效果圖

     (3)菜單顯示和隱藏的實現

       主頁面的左側邊線與手指的位置綁定,當手指向右滑動時,主頁面也會隨手指向右滑動,在這個過程中菜單頁面漸漸展示出來,實現菜單頁面隨手指滑動慢慢展開的視覺效果。

void setCurrentItemInternal(int item,int velocity) { //獲得菜單的目標狀態 item = mViewBehind.getMenuPage(item); mCurItem = item; final int destX = getDestScrollX(mCurItem); /*菜單放置狀態為左側,通過設置主頁面的位置實現菜單的彈出展示或彈回隱藏 1.destX=0,主頁面左側邊線與屏幕左側邊線對齊,菜單被全部遮擋,實現菜單彈回隱藏 2.destX=MenuWidth,主頁面左側邊線向右移動與菜單總寬度相等的距離,實現菜單彈出展示*/ if (mViewBehind.getMode() == SlidingMenu.LEFT) { mContent.setLeft(destX); mViewBehind.scrollBehindTo(destX); } ...... } // 菜單放置在左側時的菜單滑動操作 public void left_scrollto(float x) { //當menu的展示寬度大於最大寬度時僅展示最大寬度 if(x>getMenuWidth()){ x=getMenuWidth(); } //主頁面(主頁面左側邊線)和菜單(菜單右側邊線)分別移動到指定位置X mContent.setLeft((int)x); mViewBehind.scrollBehindTo((int)x); } 

 

2、CustomViewBehind 菜單頁面

        CustomViewBehind為菜單頁面,邏輯相比於主頁面簡單許多。主要負責根據主頁面中的Touch事件改變自身狀態值,同時向外暴露接口,用於設置或者獲取菜單頁面的最大寬度、自身狀態等屬性。

// 設置菜單最大寬度 public void setMenuWidth(int menuWidth) { this.menuWidth = menuWidth; } // 獲得菜單最大寬度 public int getMenuWidth() { return menuWidth; } 

 

3.  SlidingMenu

        分別實例化CustomViewAbove和CustomViewBehind的對象,並按照主頁面在上菜單頁面在下的順序分別添加到SlidingMenu的容器中。

//添加菜單子控件 addComponent(mViewBehind, behindParams); //添加主頁面子控件 addComponent(mViewAbove, aboveParams); 

 

項目貢獻人

徐澤鑫 鄭森文 朱偉 陳美汝 王佳思 張馨心

 

作者:朱偉ISRC

想了解更多內容,請訪問51CTO和華為合作共建的鴻蒙社區:https://harmonyos.51cto.com/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM