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-下滑抽屉的更多相关文章

  1. android自定义viewgroup初步之一----抽屉菜单

    转载请注明出处 http://blog.csdn.net/wingichoy/article/details/47832151 几天前在慕课网上看到鸿洋老师的 自定义卫星菜单,感觉很有意思,于是看完视 ...

  2. Android 自定义ViewGroup

    前面几节,我们重点讨论了自定义View的三板斧,这节我们来讨论自定义ViewGroup,为什么要自定义ViewGroup,其实就是为了更好的管理View. 自定义ViewGroup无非那么几步: Ⅰ. ...

  3. 简单的例子了解自定义ViewGroup(一)

    在Android中,控件可以分为ViewGroup控件与View控件.自定义View控件,我之前的文章已经说过.这次我们主要说一下自定义ViewGroup控件.ViewGroup是作为父控件可以包含多 ...

  4. Android动画效果之自定义ViewGroup添加布局动画

    前言: 前面几篇文章介绍了补间动画.逐帧动画.属性动画,大部分都是针对View来实现的动画,那么该如何为了一个ViewGroup添加动画呢?今天结合自定义ViewGroup来学习一下布局动画.本文将通 ...

  5. Android自定义控件之自定义ViewGroup实现标签云

    前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言 ...

  6. Android自定义ViewGroup

    视图分类就两类,View和ViewGroup.ViewGroup是View的子类,ViewGroup可以包含所有的View(包括ViewGroup),View只能自我描绘,不能包含其他View. 然而 ...

  7. [Android Pro] Android开发实践:自定义ViewGroup的onLayout()分析

    reference to : http://www.linuxidc.com/Linux/2014-12/110165.htm 前一篇文章主要讲了自定义View为什么要重载onMeasure()方法( ...

  8. android 手把手教您自定义ViewGroup(一)

    1.概述 在写代码之前,我必须得问几个问题: 1.ViewGroup的职责是啥? ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属 ...

  9. 自定义ViewGroup须知

    自定义ViewGroup须知: 1.必须复写onMeasure和onLayout方法,根据容器的特性进行布局设计 2.复写onMeasure方法必须处理父布局设置宽或高为wrap_content情况下 ...

随机推荐

  1. C++基础知识篇:C++ 运算符

    运算符是一种告诉编译器执行特定的数学或逻辑操作的符号.C++ 内置了丰富的运算符,并提供了以下类型的运算符: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 杂项运算符 本章将逐一介绍算术运 ...

  2. 项目、地铁/公交、游戏签到、项目上线后发现新bug该怎么处理

    项目:1.提前分配好业务(每个人该干什么 )2.提前召开会议3.提前挑好人4.准备项目思维导图5.提前审阅项目6.为确保项目按期交付 把控好时间7.给员工提前打好招呼 (提醒加班)8.建立好安全机制9 ...

  3. C语言实现聊天室(windows版本)

    来源:微信公众号「编程学习基地」 目录 C语言聊天室 运行效果 分析设计 多线程 线程的同步 服务端设计 遇到的问题 C语言聊天室 基于 tcp 实现群聊功能,本项目设计是在windows环境下基于套 ...

  4. 微信小程序 下拉刷新

    <scroll-view class='scroll-view-container' scroll-y="true" bindscrolltolower='scrollToL ...

  5. C和指针---结构和联合

    一.结构 1.C提供了两种类型的聚合数据类型---数组.结构.数组是相同类型的元素集合,它的每个元素长度相同,故可以通过下标引用或指针间接访问来选择的;而结构可以把不同类型的值存储在一起,由于结构的成 ...

  6. 如何将图片、html等格式转成pdf

    const int WWidth = 600; const int HHeight = 800; List<System.Drawing.Image> AllName = new List ...

  7. PP-OCR论文翻译

    译者注: 我有逛豆瓣社区的习惯,因此不经意间会看到一些外文翻译成中文书的评价."书是好书,翻译太臭"."中文版别看"."有能力尽量看原版". ...

  8. Python模块是否支持自定义属性使用双下划线开头和结尾?

    我们知道在Python中,变量名类似__xxx__的,也就是以双下划线开头并且以双下划线结尾的变量和方法,是特殊变量,特殊变量是可以直接访问的,不是私有变量,所以,一般实例变量和类变量以及方法不能用_ ...

  9. 基础篇——SpringCloudAlibaba分布式组件

    官方文档:https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md 想要使用SpringCloudAlibaba ...

  10. 半夜删你代码队 Day2冲刺

    一.每日站立式会议 1.站立式会议 成员 昨日完成工作 今日计划工作 遇到的困难 陈惠霖 整理任务 了解相关网页设计 任务安排有的不合理,需改进 侯晓龙 学习了解相关知识 尝试写第一个实例子 无 周楚 ...