生活随笔
收集整理的這篇文章主要介紹了
Android 自定义控件打造史上最简单的侧滑菜单
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
側滑菜單在很多應用中都會見到,最近QQ5.0側滑還玩了點花樣~~對于側滑菜單,一般大家都會自定義ViewGroup,然后隱藏菜單欄,當手指滑動時,通過Scroller或者不斷的改變leftMargin等實現;多少都有點復雜,完成以后還需要對滑動沖突等進行處理~~今天給大家帶來一個簡單的實現,史上最簡單有點夸張,但是的確是我目前遇到過的最簡單的一種實現~~~
1、原理分析
既然是側滑,無非就是在巴掌大的屏幕,塞入大概兩巴掌大的布局,需要滑動可以出現另一個,既然這樣,大家為啥不考慮使用Android提供的HorizontalScrollView呢~
如果使用HorizontalScrollView,還需要在ACTION_DOWN , ACTION_MOVE里面去監聽,判斷,不斷改變控件位置了么? NO!!!HorizontalScrollView本身就帶了滑動的功能~~
還需要自己的手動處理各種沖突么?NO!!!當然了,還是需要了解下事件分發機制的~~~
2、效果圖
嗯,主界面搞了QQ一張圖片,左邊盜用了一兄弟的布局文件~~罪過~~ 誰有好看的布局、圖片、圖標神馬的,可以給我發點,感激~
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,里面一個方向水平的LinearLayout,然后就是一個是菜單的布局,一個是主布局了~
4、自定義SlidingMenu
接下來就是我們最核心的代碼了~
[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;?? ????? ? ?? ????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)?? ????{?? ????????? ? ?? ????????if?(!once)?? ????????{?? ????????????LinearLayout?wrapper?=?(LinearLayout)?getChildAt(0);?? ????????????ViewGroup?menu?=?(ViewGroup)?wrapper.getChildAt(0);?? ????????????ViewGroup?content?=?(ViewGroup)?wrapper.getChildAt(1);?? ?????????????? ????????????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)?? ????????{?? ?????????? ????????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);?? ????}?? ?? }??
哈哈,完工~上面的演示圖,就用到這么點代碼~~
代碼怎么樣,短不短~除了設置寬度這些雜七雜八的代碼~正在處理滑動的代碼不過10行~~我說史上最簡單不為過吧~
嗯,由于代碼過于短,就不解釋了,大家自己看下注釋~
5、擴展
嗯,就下來,我們完善下程序,我準備首先把菜單布局里面改成ListView來證明我們是沒有沖突的;然后添加一個屬性讓用戶配置菜單距離右邊的邊距的值;再對外公布一個方法,點擊自動打開菜單,供用戶點擊某個按鈕,菜單慢慢滑出來~
1、添加自定義屬性
a、首先在values文件夾下新建一個attr.xml,寫入以下內容:
[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"這里我設置了100dp;
注:很多人問我,沒有提示咋辦,這樣,你clean下項目,如果你運氣好,就有提示了,嗯,運氣好~
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:?? ?????????????????? ????????????????mMenuRightPadding?=?a.getDimensionPixelSize(attr,?? ????????????????????????(int)?TypedValue.applyDimension(?? ????????????????????????????????TypedValue.COMPLEX_UNIT_DIP,?50f,?? ????????????????????????????????getResources().getDisplayMetrics()));?? ????????????????break;?? ????????????}?? ????????}?? ????????a.recycle();?? ????}??
在三個參數的構造方法中,通過TypeArray獲取就行了~
好了,這樣就行了~如果你又很多自定義屬性,按照上面的步驟來就行了~~
2、對外公布一個打開菜單的方法
首先定義一個boolean isOpen變量,用來標識我們當前菜單的狀態~~然后記得在ACTION_UP的時候改變下狀態:
[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;?? ????}?? ?? ????? ? ?? ????public?void?closeMenu()?? ????{?? ????????if?(isOpen)?? ????????{?? ????????????this.smoothScrollTo(mMenuWidth,?0);?? ????????????isOpen?=?false;?? ????????}?? ????}?? ?? ????? ? ?? ????public?void?toggle()?? ????{?? ????????if?(isOpen)?? ????????{?? ????????????closeMenu();?? ????????}?else?? ????????{?? ????????????openMenu();?? ????????}?? ????}??
順手多添加了兩個。。。
下面,我們挑一個進行測試:
主布局多添加一個按鈕,用于觸發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();?? ????}?? }??
好了,看下現在的效果圖:
我們把padding改成了100dp~
然后點擊我們的按鈕,看哈效果~~
3、添加ListView測試
好了~~ListView也測試完了~~大家可以根據自己的需求各種修改~~
對了,今天測試用QQ的目的是為了,下次我要拿上面的代碼,改造和QQ5.0一模一樣的效果,大家有興趣可以提前試一試,QQ的菜單好像是隱藏在主界面下面一樣,給人感覺不是劃出來的,我們這個例子也能做出那樣的效果,拭目以待吧;剩下就是各種縮放,透明度的動畫了~~~
源碼點擊下載
如果覺得不錯,評價下~哈~
----------------------------------------------------------------------------------------------------------
博主部分視頻已經上線,如果你不喜歡枯燥的文本,請猛戳(初錄,期待您的支持):
1、高仿微信5.2.1主界面及消息提醒
2、高仿QQ5.0側滑
3、Android智能機器人“小慕”的實現
4、Android自定義控件 打造Android流式布局和熱門標簽
總結
以上是生活随笔為你收集整理的Android 自定义控件打造史上最简单的侧滑菜单的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。