Android仿酷狗音樂自定義側(cè)滑菜單控件簡單實現(xiàn)

隨著Android的不斷成熟易核,許多絢麗的效果也在不斷的被大家開發(fā)出來嗅蔬,其中側(cè)滑的效果用到的項目很多蜘渣,用的好的更是給吸引了很多用戶济蝉。國內(nèi)像QQ和酷狗App的側(cè)滑就很給力杰刽,所以查了一些資料,并結(jié)合ViewDragHelper輔助類王滤,做了一種比較簡單的側(cè)滑實現(xiàn)方式贺嫂。

學習Android的同學注意了!J缙汀涝婉!

學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入Android學習交流群蔗怠,群號碼:364595326? 我們一起學Android墩弯!

一、實現(xiàn)效果圖

實現(xiàn)的效果基本跟酷狗App差不多寞射,因為就是仿造酷狗的~~

二渔工、實現(xiàn)原理

SlideLayout控件使用的是ViewDragHelper輔助類來實現(xiàn)的。ViewDragHelper是一個實現(xiàn)View的拖拽的神器桥温,它把View的拖拽操作變得特別的簡單引矩,不熟悉ViewDragHelper的同學請先上傳送門

要實現(xiàn)拖拽,首先需要將SlideLayout和ViewDragHelper關(guān)聯(lián)起來旺韭,然后將SlideLayout的事件交給ViewDragHelper來處理氛谜,然后在ViewDragHelper提供的回調(diào)里就可以對View進行各種操作。不過拖拽的原理都是差不多的区端,通過水平或者豎直的移動ViewGroup,然后不斷的layout和invalidate進行重繪顯示值漫。

在滑動的過程中,除了要不斷的計算滑動的位置和重繪界面织盼,還需要對子容器進行不同的動畫操作杨何,這里使用的是ViewHelper類對View做平移縮放和漸變等動畫。

另外還使用枚舉來記錄SlideLayout側(cè)滑的狀態(tài)沥邻,包括關(guān)閉危虱,打開和正在滑動。并且提供PanelSlideListener監(jiān)聽滑動的狀態(tài)唐全。這樣就可以根據(jù)不同的狀態(tài)做不同的操作埃跷。比如手動打開側(cè)滑,關(guān)閉側(cè)滑等等芦瘾。

三捌蚊、邏輯分析

這個項目實現(xiàn)的邏輯其實并不難集畅,只需要計算出ViewGroup滑動的位置近弟,然后重繪就行,其次還需要計算控件縮放和拉伸的比例等等挺智。當然對各種View的操作方法還是要比較熟悉祷愉,不然搞不明白有些邏輯要做這里做。

1. SlideLayout應(yīng)該作為一個控件容器來包容兩個子容器赦颇,一個菜單容器二鳄,一個主容器,首先我們需要獲取SlideLayout容器的寬高和兩個子容器對象

在View的onSizeChanged()方法里獲取SlideLayout的寬高媒怯,此時控件已經(jīng)測量完成

/**

* 當控件的寬高發(fā)生變化時會回調(diào)這個方法订讼,可以用來測量控件的寬高

*

* @param w

* @param h

* @param oldw

* @param oldh

*/

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

mSlideHeight = getMeasuredHeight();

mSlideWidth = getMeasuredWidth();

/**

* 初始化拖動的范圍

* 默認為屏幕寬度的60%

*/

mSlideRange = (int) (mSlideWidth * mRangePercent);

}

在View的onFinishInflate()方法里可以獲取容器對象,此時布局已經(jīng)填充

/**

* 當View填充結(jié)束時會調(diào)用這個方法扇苞,可以獲取子View對象

*/

@Override

protected void onFinishInflate() {

super.onFinishInflate();

if (getChildCount() < 2) {

throw new IllegalStateException("SlideLayout控件的子View必須大于2個");

}

if (!((getChildAt(0) instanceof ViewGroup) && (getChildAt(1) instanceof ViewGroup))) {

throw new IllegalArgumentException("SlideLayout控件的子View必須是ViewGroup");

}

mMenuContainer = (ViewGroup) getChildAt(0);

mMainContainer = (ViewGroup) getChildAt(1);

}

2. 獲取到了需要的屬性和對象之后欺殿,就可以將SlideLayout和ViewDragHelper進行綁定

首先在控件的構(gòu)造里創(chuàng)建ViewDragHelper對象,創(chuàng)建完之后會有一個回調(diào)鳖敷,而我們對View的各種操作就是在回調(diào)的各種方法里進行的

/** View的滑動的輔助類脖苏,在回調(diào)里監(jiān)聽View的各種操作

* @param forParent 要進行觸摸滑動的父控件

* @param sensitivity 控件滑動的速度,敏感度定踱,1.0f正常

* @param cb? 對View的事件發(fā)生改變的回調(diào)

*/

mDragHelper = ViewDragHelper.create(this, 1.0f, mViewCallback);

創(chuàng)建對象之后棍潘,如果此時就對View進行操作是沒有效果的,因為還需要把SlideLayout的處理事件傳遞給ViewDragHelper

/**

* 轉(zhuǎn)交攔截事件給輔助類

*

* @param ev

* @return

*/

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

final int action = MotionEventCompat.getActionMasked(ev);

if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {

mDragHelper.cancel();

return false;

}

return mDragHelper.shouldInterceptTouchEvent(ev);

}

/**

* 轉(zhuǎn)交觸摸事件給輔助類

*

* @param event

* @return

*/

@Override

public boolean onTouchEvent(MotionEvent event) {

try {

mDragHelper.processTouchEvent(event);

} catch (Exception e) {

e.printStackTrace();

}

return true;

}

最重要的地方就是ViewDragHelper的回調(diào)了,里面有很多方法亦歉,每一個都很重要恤浪,這里列舉一個對容器的滑動處理方法onViewPositionChanged()。其實邏輯也是比較簡單肴楷,就是判斷當前滑動的是哪一個容器资锰,計算容器的左邊界值,然后對容器進行重繪

/**

* 當子View的位置發(fā)送改變時回調(diào)

* @param changedView 改變的子View

* @param left 距離左邊界距離

* @param top 距離頂部距離

* @param dx 水平滑動距離差

* @param dy 豎直滑動距離差

*/

@Override

public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {

/**

* 將菜單面板的移動量給主面板

*/

if (changedView == mMenuContainer) {

mMenuContainer.layout(0, 0, mSlideWidth, mSlideHeight);

int newLeft = mMainContainer.getLeft() + dx;

newLeft = fixLeft(newLeft);

mMainContainer.layout(newLeft, 0, newLeft + mSlideWidth, mSlideHeight);

}

// 處理移動事件

performSlideEvent();

}

五阶祭、使用教程

布局文件中

xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/slideLayout"

android:layout_width="match_parent"

android:background="@mipmap/icon_bg"

android:layout_height="match_parent">

// 菜單容器

// 主容器

代碼中獲取對象绷杜,設(shè)置監(jiān)聽,設(shè)置打開或者關(guān)閉側(cè)滑

六濒募、總結(jié)

有了ViewDragHelper這個輔助類鞭盟,對ViewGroup進行操作相對來說已經(jīng)比較簡單了,只需要處理計算和繪制的工作瑰剃,其他的都已經(jīng)做好了齿诉。當然ViewDragHelper的作用遠不于此,想要了解更多的同學可以去研究一下這個類的源碼晌姚。這里也只是簡單的實現(xiàn)了側(cè)滑功能粤剧,要想做的更完美的同學

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市挥唠,隨后出現(xiàn)的幾起案子抵恋,更是在濱河造成了極大的恐慌,老刑警劉巖宝磨,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弧关,死亡現(xiàn)場離奇詭異,居然都是意外死亡唤锉,警方通過查閱死者的電腦和手機世囊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來窿祥,“玉大人株憾,你說我怎么就攤上這事∩柜茫” “怎么了嗤瞎?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長浸遗。 經(jīng)常有香客問我猫胁,道長,這世上最難降的妖魔是什么跛锌? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任弃秆,我火速辦了婚禮届惋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘菠赚。我一直安慰自己脑豹,他們只是感情好,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布衡查。 她就那樣靜靜地躺著瘩欺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拌牲。 梳的紋絲不亂的頭發(fā)上俱饿,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天,我揣著相機與錄音塌忽,去河邊找鬼拍埠。 笑死,一個胖子當著我的面吹牛土居,可吹牛的內(nèi)容都是我干的枣购。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼擦耀,長吁一口氣:“原來是場噩夢啊……” “哼棉圈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起眷蜓,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤分瘾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后账磺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芹敌,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡痊远,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年垮抗,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碧聪。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡冒版,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逞姿,到底是詐尸還是另有隱情辞嗡,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布滞造,位于F島的核電站续室,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏谒养。R本人自食惡果不足惜挺狰,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丰泊,春花似錦薯定、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至学赛,卻和暖如春年堆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盏浇。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工嘀韧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缠捌。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓锄贷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親曼月。 傳聞我的和親對象是個殘疾皇子谊却,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容