7.自定义ViewGroup-下滑抽屉
1.效果

2.思路
分析效果:
1.布局分为两部分,后面部分,前面部分,默认状态后面被挡住;
2.后面不可以滑动,前面可以滑动;
3.如果前面的布局本身是可以滑动的,那么当前面布局滑动到第一个时,后面的布局才显示出来
基于以上的效果,我们自定义ViewGroup 继承自FrameLayout,使用
ViewDragHelper处理滑动事件;当前面的view 本身是可以滑动的,那么当其手指向下move的过程中需要判断前面的view是否在最顶部,从而决定是否拦截事件;
ViewDragHelper 的用法
//重点
private ViewDragHelper mDragHelper;
//初始化
mDragHelper = ViewDragHelper.create(this, mDragCallback);
ViewDragHelper.Callback mDragCallback = new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(@NonNull View child, int pointerId) {
//只有mDragView 可以滑动
return mDragView == child;
}
@Override
public int clampViewPositionVertical(@NonNull View child, int top, int dy) {
//控制垂直方向滑动的距离
if (top < 0) {
top = 0;
}
if (top > mMenuHeight) {
top = mMenuHeight;
}
return top;
}
//当手指松开的时候回调
@Override
public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {
int dy = mDragView.getTop();
if (dy > mMenuHeight / 2) {
//打开
mDragHelper.settleCapturedViewAt(0, mMenuHeight);
} else {
//关闭
mDragHelper.settleCapturedViewAt(0, 0);
}
invalidate();
}
};
@Override
public boolean onTouchEvent(MotionEvent event) {
//处理event事件
mDragHelper.processTouchEvent(event);
return true;
}
全部代码
class VerticalDragListView extends FrameLayout {
private static final String TAG = "VerticalDragListView";
private ViewDragHelper mDragHelper;
private View mMenuView;
private View mDragView;
private int mMenuHeight;
private boolean isOpen = false;
public VerticalDragListView(@NonNull Context context) {
this(context, null);
}
public VerticalDragListView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public VerticalDragListView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mDragHelper = ViewDragHelper.create(this, mDragCallback);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mMenuView = getChildAt(0);
mDragView = getChildAt(1);
}
ViewDragHelper.Callback mDragCallback = new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(@NonNull View child, int pointerId) {
//只有mDragView 可以滑动
return mDragView == child;
}
@Override
public int clampViewPositionVertical(@NonNull View child, int top, int dy) {
//通过top 控制范围
if (top < 0) {
top = 0;
}
if (top > mMenuHeight) {
top = mMenuHeight;
}
return top;
}
@Override
public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {
int dy = mDragView.getTop();
//当手指松开的时候
if (dy > mMenuHeight / 2) {
//打开
mDragHelper.settleCapturedViewAt(0, mMenuHeight);
isOpen = true;
} else {
//关闭
mDragHelper.settleCapturedViewAt(0, 0);
isOpen = false;
}
invalidate();
}
};
@Override
public void computeScroll() {
if (mDragHelper.continueSettling(true)) {
invalidate();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mMenuHeight = mMenuView.getMeasuredHeight();
}
float downY = 0;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (isOpen) {
return true;
}
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mDragHelper.processTouchEvent(ev);
downY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
//子view滑动到顶部&&已经到顶了
if (ev.getY() - downY > 0 && !canChildScrollUp(mDragView)) {
return true;
}
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mDragHelper.processTouchEvent(event);
return true;
}
/**
* 判断是否可以继续向上滑
*
* @param mTarget
* @return
*/
public boolean canChildScrollUp(View mTarget) {
if (android.os.Build.VERSION.SDK_INT < 14) {
if (mTarget instanceof AbsListView) {
final AbsListView absListView = (AbsListView) mTarget;
return absListView.getChildCount() > 0
&& (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
.getTop() < absListView.getPaddingTop());
} else {
return mTarget.canScrollVertically(-1) || mTarget.getScrollY() > 0;
}
} else {
return mTarget.canScrollVertically(-1);
}
}
}
3.目前存在的问题
当滑动的最顶端的时候,只有松开手,再按下滑,才可以滑的动
7.自定义ViewGroup-下滑抽屉的更多相关文章
- android自定义viewgroup初步之一----抽屉菜单
转载请注明出处 http://blog.csdn.net/wingichoy/article/details/47832151 几天前在慕课网上看到鸿洋老师的 自定义卫星菜单,感觉很有意思,于是看完视 ...
- Android 自定义ViewGroup
前面几节,我们重点讨论了自定义View的三板斧,这节我们来讨论自定义ViewGroup,为什么要自定义ViewGroup,其实就是为了更好的管理View. 自定义ViewGroup无非那么几步: Ⅰ. ...
- 简单的例子了解自定义ViewGroup(一)
在Android中,控件可以分为ViewGroup控件与View控件.自定义View控件,我之前的文章已经说过.这次我们主要说一下自定义ViewGroup控件.ViewGroup是作为父控件可以包含多 ...
- Android动画效果之自定义ViewGroup添加布局动画
前言: 前面几篇文章介绍了补间动画.逐帧动画.属性动画,大部分都是针对View来实现的动画,那么该如何为了一个ViewGroup添加动画呢?今天结合自定义ViewGroup来学习一下布局动画.本文将通 ...
- Android自定义控件之自定义ViewGroup实现标签云
前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言 ...
- Android自定义ViewGroup
视图分类就两类,View和ViewGroup.ViewGroup是View的子类,ViewGroup可以包含所有的View(包括ViewGroup),View只能自我描绘,不能包含其他View. 然而 ...
- [Android Pro] Android开发实践:自定义ViewGroup的onLayout()分析
reference to : http://www.linuxidc.com/Linux/2014-12/110165.htm 前一篇文章主要讲了自定义View为什么要重载onMeasure()方法( ...
- android 手把手教您自定义ViewGroup(一)
1.概述 在写代码之前,我必须得问几个问题: 1.ViewGroup的职责是啥? ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属 ...
- 自定义ViewGroup须知
自定义ViewGroup须知: 1.必须复写onMeasure和onLayout方法,根据容器的特性进行布局设计 2.复写onMeasure方法必须处理父布局设置宽或高为wrap_content情况下 ...
随机推荐
- AppWeb认证绕过漏洞(CVE-2018-8715)
AppWeb认证绕过漏洞(CVE-2018-8715) 一.漏洞描述 Appweb简介 Appweb是一个嵌入式HTTP Web服务器,主要的设计思路是安全.这是直接集成到客户的应用和设备,便于开发和 ...
- spring bean注册和实例化
1.左边3个接口定义了基本的Ioc容器的2.HierarchicalBeanFactory增加了getParentBeanFactory()具备了双亲Ioc的管理能力3.ConfigurableBea ...
- 集群--lvs
快一个月没有更新博客了,最近一段时间在忙世界技能大赛网络系统系管理这个项目,没有太多的时间,我百忙之中更新一下.最近赛题中有说到集群这个,lvs这个东西(我也该学学这个了,一直停留在基础部分,是时候学 ...
- Java面试专题-集合篇(2)
- 懒松鼠Flink-Boot(Flink+Spring):一款将Flink与Spring生态完美融合的脚手架工程
目录 你可能面临如下苦恼: 接口缓存 重试机制 Bean校验 等等...... 它为流计算开发工程师解决了 有了它你的代码就像这样子: 仓库地址:懒松鼠Flink-Boot 1. 组织结构 2. 技术 ...
- 算法——移掉K位数字使得数值最小
给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. leetcode 解题思路:如果这个数的各个位是递增的,那么直接从最后面开始移除一定就是最最小的:如果这个数的 ...
- Spark3.0中Dates和Timestamps
Spark3.0使用的是预公历,而之前都是儒略历和公历的混合(即1582年之前的日期使用儒略历,1582年之后使用公历,java.sql.Date这个API用的就是这种,而Java8里使用java.t ...
- Notepad++ 使用步骤,熟练掌握notepad++的使用技巧,无疑会大大提升专业技能。以及快捷键操作
官方下载地址: https://notepad-plus.en.softonic.com/ 1.安装 双击安装包出现以下界面 2.点击我接受 3.安装地址 继续下一步 4.默认即可,继续下一步 5.根 ...
- WinUI 3 Preview 3 发布了,再一次试试它的性能
1. WinUI 3 在微软 Build 2020 开发者大会上,WinUI 团队宣布可公开预览的 WinUI 3 Preview 1,它让开发人员可以在 Win32 中使用 WinUI.最终 XAM ...
- jwt 简单基本使用加密解密
import jwt # 加密 encode_jwt=jwt.encode({'uid':'123'},'密钥123',algorithm='HS256') print(encode_jwt) # 解 ...