android 粘性view_Android自定义StickinessView粘性滑动效果

design包的出现,Android界面发生了巨大变化,各种滑动配合的效果,下面我就粘性滑动中的一种进行自定义,效果图如下:

大家看到效果了,这里我是继承了LinerLayout,方便一点,若果是ViewGroup的话,也就复杂一点点。这里分为三部分:

1.head1,顶部可移动的Layout。

2.head2,固定的头部,不会滑动除屏幕外。

3.可滑动的Layout(这里只可以是ListView,不过也可以是任何可滑动的View,只要给出Head可滑动的时机即可)

本StickinessView的难点在于,解决滑动冲突和事件的拦截处理,接下来我一一道来。

一、首先,要确定HeadLayout什么时候可以拦截事件,那么就要确定ListView到达顶部和底部的时机。

@Override

public void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount) {

View v = mListView.getChildAt(0);

//当firstItem的top为0的时候就认为已经到达ListView的顶部了

if (mListView.getChildCount() > 0 && firstVisibleItem == 0) {

//滑动到顶部

if (v.getTop() == 0) {

//滑动到顶部了

isListViewTop = true;

} else {

isListViewBottom = false;

}

}else if (mListView.getChildCount()>0&&firstVisibleItem+visibleItemCount==totalItemCount){

final View bottomChildView = mListView.getChildAt(mListView.getChildCount()-1);

//当最后一个itemView的bottom>=ListView的高度的时候,那么就认为到达底部了

if (mListView.getHeight()>=bottomChildView.getBottom()){

isListViewBottom = true;

}else {

isListViewBottom = false;

}

}else {

isListViewBottom = false;

isListViewTop = false;

}

原因很简单,因为View的getTop和getBottom方法是相对父容器的位置,熟悉Layout方法的,想必就会很明白了。

二、知道了HeadView拦截事件的时机,我们就要搞清楚在此基础之上,我们到底啥时候拦击点击事件,进行滑动。

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

switch (ev.getAction()) {

case MotionEvent.ACTION_DOWN:

touchY = ev.getRawY();

isIntercept = false;

break;

case MotionEvent.ACTION_MOVE:

float distant = ev.getRawY() - touchY;

if (isListViewTop) {

switch (mHeadPosition) {

case TOP:

if (distant > 0) isIntercept = true;

break;

case CENTER:

isIntercept = true;

break;

}

}

if (isListViewBottom){

switch (mHeadPosition) {

case CENTER:

isIntercept = true;

break;

case BOTTOM:

if (distant < 0) isIntercept = true;

break;

}

}

break;

case MotionEvent.ACTION_UP:

isIntercept = true;

break;

}

return isIntercept;

}

跟大家讲解一下onInterceptTouchEvent(MotionEvent ev),这个方法会最先调用,当一个事件序列拦截一次后,那么这个事件的后续事件动作就不会再调用该方法,也就是说,当该ViewGroup决定拦截某个事件后,那么它注定要消费后续的事件动作。这里贴出HeadView的位置状态

public static final int TOP = 0;//收缩状态

public static final int CENTER = 1;//中间状态

public static final int BOTTOM = 2;//展开状态

关于细节,想必大家画个图就可以知道了,注意一点:在拦截事件序列的时候,一般ACTION_DOWN事件不可以被拦截,因为拦截的话,没得意义了,后续事件就无法控制了,不可能继续往ChildView传递事件序列。

三、移动HeadView。

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

//获取不到的

break;

case MotionEvent.ACTION_MOVE:

int distant = (int) (touchY - event.getRawY());

if (getScrollY() + distant-1 < MAXY && getScrollY() + distant > 0) {

scrollTo(0,getScrollY() + distant);

}

break;

case MotionEvent.ACTION_UP:

if (getScrollY() == 0) mHeadPosition = BOTTOM;

if (getScrollY() == MAXY) mHeadPosition = TOP;

if (getScrollY() > 0 && getScrollY() < MAXY) mHeadPosition = CENTER;

if (getScrollY() > MAXY / 2) {

mScroll.startScroll(0,getScrollY(),MAXY-getScrollY(),100);

invalidate();

mHeadPosition = TOP;

}

if (getScrollY() < MAXY / 2) {

mScroll.startScroll(0,-getScrollY(),100);

invalidate();

mHeadPosition = BOTTOM;

}

break;

}

return super.onTouchEvent(event);

}

这里为了使得滑动跟家顺畅我使用了Scroller这个类,该类是专门处理弹性滑动的工具类,先初始化构造器,在调用startScroll()方法(其中四个参数:滑动的x,滑动的y,滑动x的偏移量,滑动y的偏移量),然后刷新视图,最后重写computeScroll()方法,

@Override

public void computeScroll() {

super.computeScroll();

if (mScroll.computeScrollOffset()){

scrollTo(mScroll.getCurrX(),mScroll.getCurrY());

postInvalidate();

}

}

好了,基本完成,我们还要第一时间获取HeadView的高度,那么在onMeasure()中获取比较好,并且只获取一次如下

if (MAXY == -1)

MAXY = mHeadSecond.getMeasuredHeight();

在onFinishInflate()方法中,该方法的执行标志着所有的View都已经add完毕,这里我们进行初始化是比较妥当的。

@Override

protected void onFinishInflate() {

super.onFinishInflate();

int count = getChildCount();

//本粘性布局只支持ListView

if (count == 3 && getChildAt(2) instanceof ListView)

init();

}

/**

* 初始化

*/

private void init() {

//获得子元素

mHeadFiest = getChildAt(0);

mHeadSecond = getChildAt(1);

mListView = (ListView) getChildAt(2);

mListView.setOnScrollListener(this);

mScroll = new Scroller(getContext());

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/471909.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Azure SQL 数据库:服务级别与性能问答

ShawnBice 2014 年 5 月 5 日上午 10:00 几天前&#xff0c;我发表了一篇文章&#xff0c;并就 4 月 24 日发布的适用于Windows Azure SQL 数据库的新服务级别提供了一些预料中的问题和解答&#xff0c;在其中为读者介绍了一些详细信息。在这篇跟进文章中&#xff0c;我想提…

matlab粒子图像测速工具,程序 PIVlab - 时间分辨粒子图像测速(PIV)工具: 一 联合开发网 - pudn.com...

程序所属分类&#xff1a;图形图像处理开发工具&#xff1a;matlab文件大小&#xff1a;7964KB下载次数&#xff1a;29上传日期&#xff1a;2017-07-21 11:48:16上 传 者&#xff1a;long1219说明&#xff1a; PIVlab - 时间分辨粒子图像测速(PIV)工具&#xff1a;一种基于GUI…

LeetCode 1852. 每个子数组的数字种类数(滑窗)

文章目录1. 题目2. 解题1. 题目 给你一个整数数组 nums与一个整数 k&#xff0c;请你构造一个长度 n-k1 的数组 ans&#xff0c;这个数组第i个元素 ans[i] 是每个长度为k的子数组 nums[i:ik-1] [nums[i], nums[i1], ..., nums[ik-1]]中数字的种类数。 返回这个数组 ans。 示…

python读文件出现特殊字符_python- pandas :读取列中带有特殊字符的文件

添加参数na_values ’&#xff1f;’到read_csv.样品&#xff1a;import pandas as pdimport iotempu"""Date Time,a2010-01-27 16:00:00,?2010-01-27 16:10:00,2.22010-01-27 16:30:00,1.7"""df pd.read_csv(io.StringIO(temp),na_values?)p…

娜塔莉波特曼2015哈佛毕业演讲

Hello, class of 2015.I am so honest to be here today.Dean Khurana,faculty,parents,and most especially graduating students. Thank you so much for inviting me. The Senior Class Committee. it’s genuinely one of the most exciting things I’ve ever been asked …

PHP ajax 传递中文乱码,ajax+php传递中文乱码解决办法

AJAX的乱码的出现在的原因由于XMLHTTP采用的是Unicode编码上传数据&#xff0c;而一般页面采用的是gb2312,这就造成显示页面时产生乱码。而当在获取页面时的XMLHttp返回的是utf-8编码&#xff0c;这就造成了显示产生乱码。解决方法之一就是在PHP文件中显示声明为GB2312header(&…

用chrome模拟微信浏览器访问需要OAuth2.0网页授权的页面

现在很流行微信网页小游戏&#xff0c;用html5制作的小游戏移过来&#xff0c;可以放到微信浏览器中打开&#xff0c;关键是可以做成微信分享朋友圈的形式&#xff0c;大大提高游戏的传播&#xff0c;增强好友的游戏互动。 微信浏览器中打开网页游戏效果还不错&#xff0c;对手…

LeetCode 1891. 割绳子(二分查找)

文章目录1. 题目2. 解题1. 题目 给定一个整数数组 ribbons 和一个整数 k&#xff0c;数组每项 ribbons[i] 表示第 i 条绳子的长度。 对于每条绳子&#xff0c;你可以将任意切割成一系列长度为正整数的部分&#xff0c;或者选择不进行切割。 例如&#xff0c;如果给你一条长度…

公需科目必须学吗_专业技术人员一般公需科目学习的通知

根据浙江省人力资源和社会保障厅《浙江省专业技术人员继续教育学时管理办法(试行)》(浙人社发〔2016〕63号)精神&#xff0c;专业技术人员每年度应参加继续教育不得少于90学时&#xff0c;其中专业科目不少于60学时&#xff0c;行业公需和一般公需科目不少于18学时。现将专业技…

php.ini开启命名空间,Zend Framework教程之模型Model基本规则和使用方法

本文实例讲述了Zend Framework教程之模型Model基本规则和使用方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;这里讲讲Zend中的model。其实Zend中的Model处理是相当简单的。这主要得益于autoload功能。不像其它框架&#xff0c;为model定义复杂的基类。如果要定义…

LeetCode 1618. 找出适应屏幕的最大字号(二分查找)

文章目录1. 题目2. 解题1. 题目 给定一个字符串 text。并能够在 宽为 w 高为 h 的屏幕上显示该文本。 字体数组中包含按升序排列的可用字号&#xff0c;您可以从该数组中选择任何字体大小。 您可以使用FontInfo接口来获取任何可用字体大小的任何字符的宽度和高度。 FontInf…

UML类图画法及类之间几种关系

文章目录如下&#xff1a; 一、类图画法 二、类之间的几种关系&#xff1a;泛化&#xff08;Generalization&#xff09;、实现&#xff08;Realization&#xff09;、关联&#xff08;Association&#xff09;&#xff08;又分一般关联、聚合&#xff08;Aggregation&#xff…

web前端知识点太多_web前端常见知识点

csstable布局的缺点1、Table要比其它html标记占更多的字节。(延迟下载时间&#xff0c;占用服务器更多的流量资源。)2、Tablle会阻挡浏览器渲染引擎的渲染顺序。(会延迟页面的生成速度&#xff0c;让用户等待更久的时间。)3、Table里显示图片时需要你把单个、有逻辑性的图片切成…

python可变参数教学,Python函数可变参数详解

在实际使用函数时&#xff0c;可能会遇到“不知道函数需要接受多少个实参”的情况&#xff0c;不过好在 Python 允许函数从调用语句中收集任意数量的实参。例如&#xff0c;设计一个制作披萨的函数&#xff0c;我们知道&#xff0c;披萨中可以放置很多种配料&#xff0c;但无法…

LeetCode 1634. 求两个多项式链表的和

文章目录1. 题目2. 解题1. 题目 多项式链表是一种特殊形式的链表&#xff0c;每个节点表示多项式的一项。 每个节点有三个属性&#xff1a; coefficient&#xff1a;该项的系数。项 9x4 的系数是 9 。power&#xff1a;该项的指数。项 9x4 的指数是 4 。next&#xff1a;指向…

进制A~Z,全字母26进制转化

public String to26( int x ) { StringBuffer sBuffer new StringBuffer(); int cur; x; while( x > 0 ) { sBuffer.append((char)( (( cur x % 26 ) 0 ? 25 : cur - 1) A) );x / 26; if( cur 0 ) x--; } sBuffer.reverse(); return sB uffer.toString(); } private …

es6 类的私有属性_JavaScript ES6类中的私有属性

要扩展loganfsmyth的回答&#xff1a;JavaScript中唯一真正私有的数据仍然是作用域变量。不能以与公共属性相同的方式在内部访问私有属性&#xff0c;但是可以使用范围变量来存储私有数据。作用域变量这里的方法是使用构造函数的作用域(它是私有的)来存储私有数据。要使方法能够…

python编程制作接金币游戏,闪电侠接金币的FlashMan类

python the Flash man catch coin gif animation闪电侠是美剧&#xff0c;这里是一个小游戏&#xff0c;操作闪电侠接不断冒出来的金币。本模块定义了FlashMan类。这个模块能单独运行&#xff0c;运行后用鼠标操作闪电侠移动即可。以下是部分代码预览&#xff1a;""&…

LeetCode 1660. 纠正二叉树(BFS)

文章目录1. 题目2. 解题1. 题目 你有一棵二叉树&#xff0c;这棵二叉树有个小问题&#xff0c;其中有且只有一个无效节点&#xff0c;它的右子节点错误地指向了与其在同一层且在其右侧的一个其他节点。 给定一棵这样的问题二叉树的根节点 root &#xff0c;将该无效节点及其所…

MS SQL Server 常用操作

以下为常用&#xff1a; --发邮件应该很常用吧 exec msdb.dbo.sp_send_dbmailprofile_name mail_profile, --邮件配置主档&#xff0c;通过数据库邮件配置向导生成&#xff0c;一般叫dba_profile,详细看下图recipients email_recipients, --地址&#xff0c;多个用英文逗号隔…