自定義View:側滑選單實現
上篇部落格我們們用動畫實現了側滑選單,如果感興趣可以通過傳送門去看一下。今天我們們通過另一種方式實現側滑選單
一、佈局
總佈局
<?xml version="1.0" encoding="utf-8"?>
<com.yushan.slidemenu.SlideMenu xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/slideMenu"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/dl_secondary"
layout="@layout/layout_secondary" />
<include
android:id="@+id/dl_main"
layout="@layout/layout_main" />
</com.yushan.slidemenu.SlideMenu>
這裡的佈局和動畫實現的基本上沒有區別,但是由於動畫實現的SlidingMenu繼承的是FrameLayout,而這次的SlidingMenu繼承的是ViewGroup。所以樣式如下:
二、SlidingMenu實現
- 重寫構造方法
public SlideMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public SlideMenu(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SlideMenu(Context context) {
super(context);
init(context);
}
private void init(Context context) {
scroller = new Scroller(context);
}
- 測量放置子控制元件
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
menuView = getChildAt(0);
menuViewWidth = menuView.getLayoutParams().width;
menuView.measure(menuViewWidth, heightMeasureSpec);
mainView = getChildAt(1);
mainView.measure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean bl, int l, int t, int r, int b) {
menuView.layout(l - menuViewWidth, t, l, b);
mainView.layout(l, t, r, b);
}
- 重寫onTouchEvent方法
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
break;
case MotionEvent.ACTION_MOVE:
distanceY = event.getX() - downX;
if (distanceY > 10) {
hasMove = true;
} else {
hasMove = false;
}
if (distanceY < 0) {
distanceY = 0;
} else if (distanceY > menuViewWidth) {
distanceY = menuViewWidth;
}
scrollTo((int) distanceY);
break;
case MotionEvent.ACTION_UP:
if (hasMove) {
if (distanceY > menuViewWidth / 2) {
oldDistanceY = menuViewWidth;
mState = DragState.Open;
} else {
oldDistanceY = 0;
mState = DragState.Close;
}
int startX = (int) distanceY;
int destX = (int) oldDistanceY;
animationScroll(startX, destX);
} else {
if (mState != DragState.Close) {
showMenu();
}
}
hasMove = false;
break;
}
return true;
}
- 點選按鈕顯示/隱藏側滑選單
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.iv_menu:
slideMenu.showMenu();
break;
}
}
SlidingMenu中程式碼:
/**
* 方法功能:側拉選單的顯示與隱藏
*/
public void showMenu() {
int startX;
int destX;
if (oldDistanceY > 0) {
startX = menuViewWidth;
destX = 0;
mState = DragState.Close;
} else {
startX = 0;
destX = menuViewWidth;
mState = DragState.Open;
}
oldDistanceY = destX;
animationScroll(startX, destX);
}
- 側滑選單的自動歸位
/**
* 方法功能:自動歸位
*
* @param startX
* @param destX
*/
private void animationScroll(int startX, int destX) {
int distanceX = destX - startX;
int startY = 0;
int distanceY = 0;
float maxDuration = 1000f;
float maxMoveDistance = menuViewWidth;
float scale = maxDuration / maxMoveDistance;
int duration = (int) (Math.abs(distanceX) - scale);
scroller.startScroll(startX, startY, distanceX, distanceY, duration);
invalidate();
}
這裡道長用到了invalidate()這個方法重新繪製介面。但是需要注意的是:invalidate()方法不能直接在子執行緒中呼叫。Android UI操作並不是執行緒安全的,並且這些操作必須在UI執行緒中呼叫。子執行緒中重新整理介面可以通過Handler來通知UI執行緒呼叫invalidate()來進行介面更新。當然API提供了另一個方法來實現子執行緒中重新整理介面的方法postInvalidate()。使用postInvalidate()重新整理介面可以直接在子執行緒中呼叫postInvalidate()。
到這裡側滑選單就實現了,這種實現方式與側滑選單實現的最大的區別在於事件攔截操作方式,希望這篇部落格可以給你提供一些幫助。下面是Demo的連結,如果需要可以去github下載
原始碼下載
相關文章
- 自定義View:側滑選單動畫實現View動畫
- 自定義view——仿酷狗的側滑選單View
- 自定義ViewGroup,實現Android的側滑選單ViewAndroid
- 自定義RecyclerView實現側滑刪除View
- Android自定義View(四)側滑佈局AndroidView
- 自定義控制元件?試試300行程式碼實現QQ側滑選單控制元件行程
- android的左右側滑選單實現Android
- css3實現側邊滑動選單CSSS3
- 利用DrawerLayout實現側滑選單學習總結
- 自定義View:畫布實現自定義View(折線圖的實現)View
- (有圖)仿QQ側滑選單:RecyclerView側滑選單,長按拖拽,滑動刪除View
- layui自定義ajax左側三級選單UI
- 原生Android 側滑選單實踐(部分)Android
- 自定義View:自定義屬性(自定義按鈕實現)View
- flutter-簡單實現找妹子自定義viewFlutterView
- Flutter自定義View的實現FlutterView
- 自定義view實現半圓環View
- 【朝花夕拾】Android自定義View篇之(十一)View的滑動,彈性滑動與自定義PagerViewAndroidView
- Android側滑選單DrawerLayout使用Android
- Swift - 仿寫QQ側滑選單Swift
- Android 自定義View 滑動解鎖AndroidView
- 自定義通過PopupWindow實現通用選單
- 短視訊平臺開發,依靠DrawerLayout實現側滑選單效果
- android利用RecyclerView+自定義View實現城市選擇介面AndroidView
- Flutter 側滑欄及城市選擇UI的實現FlutterUI
- 自定義view實現圓角圖片View
- Flutter:手把手教你實現一個仿QQ側滑選單的功能Flutter
- 簡單介紹Android自定義View實現時鐘功能AndroidView
- 實現 UITableViewCell 側滑操作列表UIView
- android 滑動刪除的listview(自定義view)AndroidView
- Android自定義View——從零開始實現可展開收起的水平選單欄AndroidView
- Flutter | 超簡單仿微信QQ側滑選單元件Flutter元件
- 深入瞭解View實現原理以及自定義View詳解View
- 自定義view之實現日曆介面(一)View
- 自定義view之實現日曆介面(二)View
- jQuery實現左側分類選單jQuery
- Android開發自定義View之滑動按鈕與自定義屬性AndroidView
- 自定義右鍵選單實現過程詳解