網站首頁 編程語言 正文
前言
在項目中,我們經常自定義ViewGroup,有時候需要拖拽它的子View,讓其運動,一般情況下如果我們手動處理各種滑動事件,非常麻煩,谷歌給我們提供了一個輔助類ViewDragHelper,ViewDragHelper給我們提供了很多拖拽相關的方法以及狀態跟蹤。
創建實例
ViewDragHelper.create(vp, callback);
ViewDragHelper的創建比較簡單,它的構造函數是私有的,只能通過create()方法創建,第一個參數是一個ViewGroup,也就是需要使用ViewDragHelper的自定義View,第二個參數callback,提供了很多拖拽相關的回調。
ViewDragHelper.Callback
下面是幾個常用的方法
private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
public boolean tryCaptureView(View child, int pointerId)
public int getViewHorizontalDragRange(View child)
public int clampViewPositionHorizontal(View child, int left, int dx)
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy)
public void onViewReleased(View releasedChild, float xvel, float yvel)
- tryCaptureView返回一個boolean,用戶判斷是否捕獲當前view的觸摸事件
- getViewHorizontalDragRange獲取child水平方向的拖拽范圍
- clampViewPositionHorizontal控制child在水平方向的移動,我們可以通過dx修正left的值,返回值表示我們真正想讓child的left變成的值
- clampViewPositionVertical和水平方向類似
- onViewPositionChanged 當child位置改變時候的回調
- onViewReleased當拖拽的view釋放的時候回調
使用
自定義一個簡單的側拉菜單,該菜單有兩個子View,一個主界面,一個側邊菜單界面
首先自定義一個ViewGroup并初始化ViewDragHelper
public class SlideMenu extends FrameLayout{
private void init(){
viewDragHelper = ViewDragHelper.create(this, callback);
}
}
然后重寫onInterceptTouchEvent和onTouchEvent,將這兩個方法的處理邏輯交給ViewDragHelper
public boolean onInterceptTouchEvent(MotionEvent ev) {
return viewDragHelper.shouldInterceptTouchEvent(ev);
}
public boolean onTouchEvent(MotionEvent event) {
viewDragHelper.processTouchEvent(event);
return true;
}
實現ViewDragHelper.Callback,重寫tryCaptureView,在當前Layout中兩個子VIew都需要滑動,所以直接返回true.
public boolean tryCaptureView(View child, int pointerId) {
return true;
}
先限制一下橫向滑動范圍,給一個最大值
public int getViewHorizontalDragRange(View child) {
return (int) dragRange;
}
主界面在滑動過程中,我們需要控制下它在水平方向的移動距離
public int clampViewPositionHorizontal(View child, int left, int dx) {
if(child==mainView){
if(left<0)left=0;//限制mainView的左邊
if(left>dragRange)left=(int) dragRange;//限制mainView的右邊
}
return left;
}
在滑動過程中,根據拖拽回調重新對側拉菜單和主界面布局,不斷刷新他們的位置信息,這里簡單起見,讓側拉菜單固定,只是主界面滑動。
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
if(changedView==menuView){
menuView.layout(0, 0, menuView.getMeasuredWidth(),menuView.getMeasuredHeight());
int newLeft = mainView.getLeft()+dx;
if(newLeft<0)newLeft=0;
if(newLeft>dragRange)newLeft=(int) dragRange;mainView.layout(newLeft,mainView.getTop()+dy,newLeft+mainView.getMeasuredWidth(),mainView.getBottom()+dy);
}
}
當手指抬起釋放view的時候,可能我們只是拖拽了一點,這時候我們需要根據當前拖拽的信息決定是打開菜單還是關閉菜單。
public void onViewReleased(View releasedChild, float xvel, float yvel) {
if(mainView.getLeft()<dragRange/2){
//在左半邊
close();
}else {
//在右半邊
open();
}
}
對于view的滑動ViewDragHelper也提供了smoothSlideViewTo方法,所以close和open方法就很簡單
public void close() {
viewDragHelper.smoothSlideViewTo(mainView,0,mainView.getTop());
ViewCompat.postInvalidateOnAnimation(SlideMenu.this);
}
public void computeScroll() {
if(viewDragHelper.continueSettling(true)){
ViewCompat.postInvalidateOnAnimation(SlideMenu.this);
}
}
然后還可以提供一些拖拽狀態回調,比如拖拽完成,拖拽中等狀態,這些比較簡單,直接在onViewPositionChanged中處理就可以了。
最后看一下效果
總結
原文鏈接:https://juejin.cn/post/7092034773136179237
相關推薦
- 2022-07-04 PyG搭建GCN模型實現節點分類GCNConv參數詳解_python
- 2022-11-23 詳解Android消息機制完整的執行流程_Android
- 2022-05-26 flutter實現底部抽屜效果_Android
- 2022-05-15 Docker基本概念和底層原理解析_docker
- 2022-07-12 解決錯誤:org.apache.ibatis.binding.BindingException
- 2024-07-13 IDEA無法使用@WebServlet()注解
- 2022-09-09 python如何利用turtle繪制正方形_python
- 2022-07-31 C語言數據結構算法基礎之循環隊列示例_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支