日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android 自定义控件打造史上最简单的侧滑菜单

發(fā)布時(shí)間:2025/6/15 Android 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 自定义控件打造史上最简单的侧滑菜单 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

側(cè)滑菜單在很多應(yīng)用中都會(huì)見到,最近QQ5.0側(cè)滑還玩了點(diǎn)花樣~~對(duì)于側(cè)滑菜單,一般大家都會(huì)自定義ViewGroup,然后隱藏菜單欄,當(dāng)手指滑動(dòng)時(shí),通過Scroller或者不斷的改變leftMargin等實(shí)現(xiàn);多少都有點(diǎn)復(fù)雜,完成以后還需要對(duì)滑動(dòng)沖突等進(jìn)行處理~~今天給大家?guī)?lái)一個(gè)簡(jiǎn)單的實(shí)現(xiàn),史上最簡(jiǎn)單有點(diǎn)夸張,但是的確是我目前遇到過的最簡(jiǎn)單的一種實(shí)現(xiàn)~~~

1、原理分析

既然是側(cè)滑,無(wú)非就是在巴掌大的屏幕,塞入大概兩巴掌大的布局,需要滑動(dòng)可以出現(xiàn)另一個(gè),既然這樣,大家為啥不考慮使用Android提供的HorizontalScrollView呢~

如果使用HorizontalScrollView,還需要在ACTION_DOWN , ACTION_MOVE里面去監(jiān)聽,判斷,不斷改變控件位置了么? NO!!!HorizontalScrollView本身就帶了滑動(dòng)的功能~~

還需要自己的手動(dòng)處理各種沖突么?NO!!!當(dāng)然了,還是需要了解下事件分發(fā)機(jī)制的~~~

2、效果圖


嗯,主界面搞了QQ一張圖片,左邊盜用了一兄弟的布局文件~~罪過~~ 誰(shuí)有好看的布局、圖片、圖標(biāo)神馬的,可以給我發(fā)點(diǎn),感激~

3、布局文件

[html]?view plaincopy
  • <com.example.zhy_slidingmenu.SlidingMenu?xmlns:android="http://schemas.android.com/apk/res/android"??
  • ????xmlns:tools="http://schemas.android.com/tools"??
  • ????android:layout_width="wrap_content"??
  • ????android:layout_height="fill_parent"??
  • ????android:scrollbars="none"?>??
  • ??
  • ????<LinearLayout??
  • ????????android:layout_width="wrap_content"??
  • ????????android:layout_height="fill_parent"??
  • ????????android:orientation="horizontal"?>??
  • ??
  • ????????<include?layout="@layout/layout_menu"?/>??
  • ??
  • ????????<LinearLayout??
  • ????????????android:layout_width="fill_parent"??
  • ????????????android:layout_height="fill_parent"??
  • ????????????android:background="@drawable/qq"?>??
  • ????????</LinearLayout>??
  • ????</LinearLayout>??
  • ??
  • </com.example.zhy_slidingmenu.SlidingMenu>??

  • 首先是我們的自定義View,里面一個(gè)方向水平的LinearLayout,然后就是一個(gè)是菜單的布局,一個(gè)是主布局了~

    4、自定義SlidingMenu

    接下來(lái)就是我們最核心的代碼了~

    [java]?view plaincopy
  • package?com.example.zhy_slidingmenu;??
  • ??
  • import?android.content.Context;??
  • import?android.util.AttributeSet;??
  • import?android.util.TypedValue;??
  • import?android.view.MotionEvent;??
  • import?android.view.ViewGroup;??
  • import?android.widget.HorizontalScrollView;??
  • import?android.widget.LinearLayout;??
  • ??
  • import?com.zhy.utils.ScreenUtils;??
  • ??
  • public?class?SlidingMenu?extends?HorizontalScrollView??
  • {??
  • ????/**?
  • ?????*?屏幕寬度?
  • ?????*/??
  • ????private?int?mScreenWidth;??
  • ????/**?
  • ?????*?dp?
  • ?????*/??
  • ????private?int?mMenuRightPadding?=?50;??
  • ????/**?
  • ?????*?菜單的寬度?
  • ?????*/??
  • ????private?int?mMenuWidth;??
  • ????private?int?mHalfMenuWidth;??
  • ??
  • ????private?boolean?once;??
  • ??
  • ????public?SlidingMenu(Context?context,?AttributeSet?attrs)??
  • ????{??
  • ????????super(context,?attrs);??
  • ????????mScreenWidth?=?ScreenUtils.getScreenWidth(context);??
  • ????}??
  • ??
  • ????@Override??
  • ????protected?void?onMeasure(int?widthMeasureSpec,?int?heightMeasureSpec)??
  • ????{??
  • ????????/**?
  • ?????????*?顯示的設(shè)置一個(gè)寬度?
  • ?????????*/??
  • ????????if?(!once)??
  • ????????{??
  • ????????????LinearLayout?wrapper?=?(LinearLayout)?getChildAt(0);??
  • ????????????ViewGroup?menu?=?(ViewGroup)?wrapper.getChildAt(0);??
  • ????????????ViewGroup?content?=?(ViewGroup)?wrapper.getChildAt(1);??
  • ????????????//?dp?to?px??
  • ????????????mMenuRightPadding?=?(int)?TypedValue.applyDimension(??
  • ????????????????????TypedValue.COMPLEX_UNIT_DIP,?mMenuRightPadding,?content??
  • ????????????????????????????.getResources().getDisplayMetrics());??
  • ??
  • ????????????mMenuWidth?=?mScreenWidth?-?mMenuRightPadding;??
  • ????????????mHalfMenuWidth?=?mMenuWidth?/?2;??
  • ????????????menu.getLayoutParams().width?=?mMenuWidth;??
  • ????????????content.getLayoutParams().width?=?mScreenWidth;??
  • ??
  • ????????}??
  • ????????super.onMeasure(widthMeasureSpec,?heightMeasureSpec);??
  • ??
  • ????}??
  • ??
  • ????@Override??
  • ????protected?void?onLayout(boolean?changed,?int?l,?int?t,?int?r,?int?b)??
  • ????{??
  • ????????super.onLayout(changed,?l,?t,?r,?b);??
  • ????????if?(changed)??
  • ????????{??
  • ????????????//?將菜單隱藏??
  • ????????????this.scrollTo(mMenuWidth,?0);??
  • ????????????once?=?true;??
  • ????????}??
  • ????}??
  • ??
  • ????@Override??
  • ????public?boolean?onTouchEvent(MotionEvent?ev)??
  • ????{??
  • ????????int?action?=?ev.getAction();??
  • ????????switch?(action)??
  • ????????{??
  • ????????//?Up時(shí),進(jìn)行判斷,如果顯示區(qū)域大于菜單寬度一半則完全顯示,否則隱藏??
  • ????????case?MotionEvent.ACTION_UP:??
  • ????????????int?scrollX?=?getScrollX();??
  • ????????????if?(scrollX?>?mHalfMenuWidth)??
  • ????????????????this.smoothScrollTo(mMenuWidth,?0);??
  • ????????????else??
  • ????????????????this.smoothScrollTo(0,?0);??
  • ????????????return?true;??
  • ????????}??
  • ????????return?super.onTouchEvent(ev);??
  • ????}??
  • ??
  • }??

  • 哈哈,完工~上面的演示圖,就用到這么點(diǎn)代碼~~

    代碼怎么樣,短不短~除了設(shè)置寬度這些雜七雜八的代碼~正在處理滑動(dòng)的代碼不過10行~~我說史上最簡(jiǎn)單不為過吧~

    嗯,由于代碼過于短,就不解釋了,大家自己看下注釋~

    5、擴(kuò)展

    嗯,就下來(lái),我們完善下程序,我準(zhǔn)備首先把菜單布局里面改成ListView來(lái)證明我們是沒有沖突的;然后添加一個(gè)屬性讓用戶配置菜單距離右邊的邊距的值;再對(duì)外公布一個(gè)方法,點(diǎn)擊自動(dòng)打開菜單,供用戶點(diǎn)擊某個(gè)按鈕,菜單慢慢滑出來(lái)~

    1、添加自定義屬性

    a、首先在values文件夾下新建一個(gè)attr.xml,寫入以下內(nèi)容:

    [html]?view plaincopy
  • <?xml?version="1.0"?encoding="utf-8"?>??
  • <resources>??
  • ??
  • ????<attr?name="rightPadding"?format="dimension"?/>??
  • ??
  • ????<declare-styleable?name="SlidingMenu">??
  • ????????<attr?name="rightPadding"?/>??
  • ????</declare-styleable>??
  • ??
  • </resources>??
  • b、在布局中聲明命名空間和使用屬性

    定義完了,肯定要使用么。

    [html]?view plaincopy
  • <com.example.zhy_slidingmenu.SlidingMenu?xmlns:android="http://schemas.android.com/apk/res/android"??
  • ????xmlns:tools="http://schemas.android.com/tools"??
  • ????xmlns:zhy="http://schemas.android.com/apk/res/com.example.zhy_slidingmenu"??
  • ????android:layout_width="wrap_content"??
  • ????android:layout_height="fill_parent"??
  • ????android:scrollbars="none"??
  • ????zhy:rightPadding="100dp"?>??

  • 可以看到我們的命名空間:xmlns:zhy="http://schemas.android.com/apk/res/com.example.zhy_slidingmenu" 是http://schemas.android.com/apk/res/加上我們的包名;

    我們的屬性:zhy:rightPadding="100dp"這里我設(shè)置了100dp;

    注:很多人問我,沒有提示咋辦,這樣,你clean下項(xiàng)目,如果你運(yùn)氣好,就有提示了,嗯,運(yùn)氣好~

    c、在我們自定義類中獲得屬性

    [java]?view plaincopy
  • public?SlidingMenu(Context?context,?AttributeSet?attrs,?int?defStyle)??
  • ????{??
  • ????????super(context,?attrs,?defStyle);??
  • ????????mScreenWidth?=?ScreenUtils.getScreenWidth(context);??
  • ??
  • ????????TypedArray?a?=?context.getTheme().obtainStyledAttributes(attrs,??
  • ????????????????R.styleable.SlidingMenu,?defStyle,?0);??
  • ????????int?n?=?a.getIndexCount();??
  • ????????for?(int?i?=?0;?i?<?n;?i++)??
  • ????????{??
  • ????????????int?attr?=?a.getIndex(i);??
  • ????????????switch?(attr)??
  • ????????????{??
  • ????????????case?R.styleable.SlidingMenu_rightPadding:??
  • ????????????????//?默認(rèn)50??
  • ????????????????mMenuRightPadding?=?a.getDimensionPixelSize(attr,??
  • ????????????????????????(int)?TypedValue.applyDimension(??
  • ????????????????????????????????TypedValue.COMPLEX_UNIT_DIP,?50f,??
  • ????????????????????????????????getResources().getDisplayMetrics()));//?默認(rèn)為10DP??
  • ????????????????break;??
  • ????????????}??
  • ????????}??
  • ????????a.recycle();??
  • ????}??

  • 在三個(gè)參數(shù)的構(gòu)造方法中,通過TypeArray獲取就行了~

    好了,這樣就行了~如果你又很多自定義屬性,按照上面的步驟來(lái)就行了~~

    2、對(duì)外公布一個(gè)打開菜單的方法

    首先定義一個(gè)boolean isOpen變量,用來(lái)標(biāo)識(shí)我們當(dāng)前菜單的狀態(tài)~~然后記得在ACTION_UP的時(shí)候改變下狀態(tài):

    [java]?view plaincopy
  • case?MotionEvent.ACTION_UP:??
  • ????????????int?scrollX?=?getScrollX();??
  • ????????????if?(scrollX?>?mHalfMenuWidth)??
  • ????????????{??
  • ????????????????this.smoothScrollTo(mMenuWidth,?0);??
  • ????????????????isOpen?=?false;??
  • ????????????}?else??
  • ????????????{??
  • ????????????????this.smoothScrollTo(0,?0);??
  • ????????????????isOpen?=?true;??
  • ????????????}??
  • ????????????return?true;??
  • ????????}??

  • 下面開始添加方法:

    [java]?view plaincopy
  • /**?
  • ?????*?打開菜單?
  • ?????*/??
  • ????public?void?openMenu()??
  • ????{??
  • ????????if?(isOpen)??
  • ????????????return;??
  • ????????this.smoothScrollTo(0,?0);??
  • ????????isOpen?=?true;??
  • ????}??
  • ??
  • ????/**?
  • ?????*?關(guān)閉菜單?
  • ?????*/??
  • ????public?void?closeMenu()??
  • ????{??
  • ????????if?(isOpen)??
  • ????????{??
  • ????????????this.smoothScrollTo(mMenuWidth,?0);??
  • ????????????isOpen?=?false;??
  • ????????}??
  • ????}??
  • ??
  • ????/**?
  • ?????*?切換菜單狀態(tài)?
  • ?????*/??
  • ????public?void?toggle()??
  • ????{??
  • ????????if?(isOpen)??
  • ????????{??
  • ????????????closeMenu();??
  • ????????}?else??
  • ????????{??
  • ????????????openMenu();??
  • ????????}??
  • ????}??

  • 順手多添加了兩個(gè)。。。

    下面,我們挑一個(gè)進(jìn)行測(cè)試:

    主布局多添加一個(gè)按鈕,用于觸發(fā)toggleMenu()方法

    主Activity

    [java]?view plaincopy
  • public?class?MainActivity?extends?Activity??
  • {??
  • ????private?SlidingMenu?mMenu?;???
  • ??
  • ????@Override??
  • ????protected?void?onCreate(Bundle?savedInstanceState)??
  • ????{??
  • ????????super.onCreate(savedInstanceState);??
  • ????????requestWindowFeature(Window.FEATURE_NO_TITLE);??
  • ????????setContentView(R.layout.activity_main);??
  • ????????mMenu?=?(SlidingMenu)?findViewById(R.id.id_menu);??
  • ????}??
  • ??????
  • ????public?void?toggleMenu(View?view)??
  • ????{??
  • ????????mMenu.toggle();??
  • ????}??
  • }??

  • 好了,看下現(xiàn)在的效果圖:


    我們把padding改成了100dp~

    然后點(diǎn)擊我們的按鈕,看哈效果~~

    3、添加ListView測(cè)試


    好了~~ListView也測(cè)試完了~~大家可以根據(jù)自己的需求各種修改~~

    對(duì)了,今天測(cè)試用QQ的目的是為了,下次我要拿上面的代碼,改造和QQ5.0一模一樣的效果,大家有興趣可以提前試一試,QQ的菜單好像是隱藏在主界面下面一樣,給人感覺不是劃出來(lái)的,我們這個(gè)例子也能做出那樣的效果,拭目以待吧;剩下就是各種縮放,透明度的動(dòng)畫了~~~


    源碼點(diǎn)擊下載


    如果覺得不錯(cuò),評(píng)價(jià)下~哈~


    ----------------------------------------------------------------------------------------------------------

    博主部分視頻已經(jīng)上線,如果你不喜歡枯燥的文本,請(qǐng)猛戳(初錄,期待您的支持):

    1、高仿微信5.2.1主界面及消息提醒

    2、高仿QQ5.0側(cè)滑

    3、Android智能機(jī)器人“小慕”的實(shí)現(xiàn)

    4、Android自定義控件 打造Android流式布局和熱門標(biāo)簽


    總結(jié)

    以上是生活随笔為你收集整理的Android 自定义控件打造史上最简单的侧滑菜单的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。