編輯:關於Android編程
側滑菜單在很多應用中都會見到,最近QQ5.0側滑還玩了點花樣~~對於側滑菜單,一般大家都會自定義ViewGroup,然後隱藏菜單欄,當手指滑動時,通過Scroller或者不斷的改變leftMargin等實現;多少都有點復雜,完成以後還需要對滑動沖突等進行處理~~今天給大家帶來一個簡單的實現,史上最簡單有點誇張,但是的確是我目前遇到過的最簡單的一種實現~~~
既然是側滑,無非就是在巴掌大的屏幕,塞入大概兩巴掌大的布局,需要滑動可以出現另一個,既然這樣,大家為啥不考慮使用Android提供的HorizontalScrollView呢~
如果使用HorizontalScrollView,還需要在ACTION_DOWN , ACTION_MOVE裡面去監聽,判斷,不斷改變控件位置了麼? NO!!!HorizontalScrollView本身就帶了滑動的功能~~
還需要自己的手動處理各種沖突麼?NO!!!當然了,還是需要了解下事件分發機制的~~~

嗯,主界面搞了QQ一張圖片,左邊盜用了一兄弟的布局文件~~罪過~~ 誰有好看的布局、圖片、圖標神馬的,可以給我發點,感激~
接下來就是我們最核心的代碼了~
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)
{
/**
* 顯示的設置一個寬度
*/
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時,進行判斷,如果顯示區域大於菜單寬度一半則完全顯示,否則隱藏
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行~~我說史上最簡單不為過吧~
嗯,由於代碼過於短,就不解釋了,大家自己看下注釋~
嗯,就下來,我們完善下程序,我准備首先把菜單布局裡面改成ListView來證明我們是沒有沖突的;然後添加一個屬性讓用戶配置菜單距離右邊的邊距的值;再對外公布一個方法,點擊自動打開菜單,供用戶點擊某個按鈕,菜單慢慢滑出來~
a、首先在values文件夾下新建一個attr.xml,寫入以下內容:
b、在布局中聲明命名空間和使用屬性
定義完了,肯定要使用麼。
我們的屬性:zhy:rightPadding=100dp這裡我設置了100dp;
注:很多人問我,沒有提示咋辦,這樣,你clean下項目,如果你運氣好,就有提示了,嗯,運氣好~
c、在我們自定義類中獲得屬性
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:
// 默認50
mMenuRightPadding = a.getDimensionPixelSize(attr,
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 50f,
getResources().getDisplayMetrics()));// 默認為10DP
break;
}
}
a.recycle();
}
好了,這樣就行了~如果你又很多自定義屬性,按照上面的步驟來就行了~~
首先定義一個boolean isOpen變量,用來標識我們當前菜單的狀態~~然後記得在ACTION_UP的時候改變下狀態:
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;
}
下面開始添加方法:
/**
* 打開菜單
*/
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
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~
然後點擊我們的按鈕,看哈效果~~

好了~~ListView也測試完了~~大家可以根據自己的需求各種修改~~
對了,今天測試用QQ的目的是為了,下次我要拿上面的代碼,改造和QQ5.0一模一樣的效果,大家有興趣可以提前試一試,QQ的菜單好像是隱藏在主界面下面一樣,給人感覺不是劃出來的,我們這個例子也能做出那樣的效果,拭目以待吧;剩下就是各種縮放,透明度的動畫了~~~
源碼點擊下載
如果覺得不錯,評價下~哈~
Android實現app應用多語言切換功能
最近在做一個多語言切換的功能,類似於微信的語言切換,搜了下資料基本上都是以下這種:1. 實現的效果 和微信類似,在設置界面打開切換語言的界面,選擇語言後重啟 H
Android-基本控件(Ratingbar 實現)
1.回顧上篇學習 Android 布局 優化的知識 ,和 SeekBar (可拖動 滾動條)的理解與學習2.重點(1)RatingBar 的實現(2)OnRatingBa
Android照片牆完整版,完美結合LruCache和DiskLruCache
在上一篇文章當中,我們學習了DiskLruCache的概念和基本用法,但僅僅是掌握理論知識顯然是不夠的,那麼本篇文章我們就來繼續進階一下,看一看在實戰當中應
Android Listview點贊問題關於圖片重復問題
《最近做一個小功能遇到這麼一個問題,listview 與 baseadapter結合使用,關於點贊的的時候 圖片重復問題,比如:我在第1個item 點贊然後 心型換成了紅
android6.0 Activity(五) Activity的測量(Measure)、布局(Layout)和繪制(Draw)
Android應用程序窗口的繪圖表面在創建完成之後,我們就可以從上到下地