# PullLoadMoreCopyWeixinAndQQ
仿微信小程序和QQ头部下拉展开更多布局项目,主要参考来源于Github项目[PullLoadXiaochengxu](https://github.com/LucianZhang/PullLoadXiaochengxu);
本项目改造主要是优化中间内容布局是ListView、RecyclerView或ScrollView等可滚动view时与头部或底部滑动存在的滑动冲突问题,以及参考QQ,处理头部收起以及底部收起时的回弹效果<br>
**效果演示如下:**<br>
![](https://github.com/oukanggui/PullLoadMoreCopyWeixinAndQQ/blob/master/app/gif/yanshi.gif)<br>
关键点是确定事件拦截的临界点,处理好事件分发,本人已在代码中添加了详细的注解说明,有兴趣的同行可以Review查看,共同学习<br>
**事件拦截与消耗代码处理,具体流程可以查看代码中的Log说明,完整代码可以下载demo查看**<br>
```java
@Override
public final boolean onInterceptTouchEvent(MotionEvent event) {
Log.d(TAG, "onInterceptTouchEvent");
if (!isInterceptTouchEventEnabled()) {
return false;
}
if (!isPullLoadEnabled() && !isPullRefreshEnabled()) {
return false;
}
final int action = event.getAction();
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
mIsHandledTouchEvent = false;
return false;
}
if (action != MotionEvent.ACTION_DOWN && mIsHandledTouchEvent) {
return true;
}
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.d(TAG, "onInterceptTouchEvent,MotionEvent.ACTION_DOWN");
mLastMotionX = event.getX();
mLastMotionY = event.getY();
mIsHandledTouchEvent = false;
break;
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "onInterceptTouchEvent,MotionEvent.ACTION_MOVE");
final float deltaX = event.getX() - mLastMotionX;
final float deltaY = event.getY() - mLastMotionY;
final float absDiff = Math.abs(deltaY);
// 位移差大于mTouchSlop,这是为了防止快速拖动引发刷新
// if ((absDiff > mTouchSlop)) {
mLastMotionX = event.getX();
mLastMotionY = event.getY();
// 第一步,先处理处理是否处于横滑状态
if (Math.abs(deltaX) >= Math.abs(deltaY)) {
Log.e(TAG, "onInterceptTouchEvent,MotionEvent.ACTION_MOVE,当前处于横滑状态,不拦截,交由父类去处理");
return false;
}
mPullDown = deltaY > 0;
if (mPullDown) {
Log.d(TAG, "当前处于下拉操作");
//下拉需要考虑如下情况:
// 1、头部处理
// 1)刷新View已到达顶部,判断是否需要
if (isPullRefreshEnabled() && checkIsContentViewScrollToTop((int) event.getX(), (int) event.getY())) {
Log.d(TAG, "当前处于下拉操作,且内容view已到达顶部,拦截,自己消耗处理,展开头部");
return true;
} else if (isPullLoadEnabled() && mFooterLayout.getState() == IExtendLayout.State.arrivedListHeight && checkIsContentViewScrollToBottom((int) event.getX(), (int) event.getY())) {
Log.d(TAG, "当前处于下拉操作,且内容view已底部且已是展开状态,拦截,自己消耗处理,收缩底部");
return true;
} else {
Log.d(TAG, "当前处于下拉操作,且内容view没有到达顶部/到达底部,不拦截,给子view进行处理,滚动列表");
return false;
}
} else {
Log.d(TAG, "当前处于上拉操作");
if (isPullRefreshEnabled() && mHeaderLayout.getState() == IExtendLayout.State.arrivedListHeight && checkIsContentViewScrollToTop((int) event.getX(), (int) event.getY())) {
Log.d(TAG, "当前处于上拉操作,头部已完全展开,且内容view已到达顶部,拦截,自己消耗处理,用于头部收缩");
return true;
} else if (isPullLoadEnabled() && checkIsContentViewScrollToBottom((int) event.getX(), (int) event.getY())) {
Log.d(TAG, "当前处于上拉操作,内容view已到达底部,拦截,自己消耗处理,用于底部展开");
return true;
} else {
Log.d(TAG, "当前处于上拉操作,且内容view没有到达顶部/到达底部,不拦截,给子view进行处理,滚动列表");
return false;
}
}
// }else{
// Log.d(TAG,"absDiff <= mTouchSlop,认为不滚动,不处理");
// }
case MotionEvent.ACTION_UP:
Log.d(TAG, "onInterceptTouchEvent,MotionEvent.ACTION_UP");
break;
default:
break;
}
return super.onInterceptTouchEvent(event);
}
@Override
public final boolean onTouchEvent(MotionEvent ev) {
boolean handled = false;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d(TAG, "onTouchEvent,MotionEvent.ACTION_DOWN");
mLastMotionY = ev.getY();
mIsHandledTouchEvent = false;
break;
case MotionEvent.ACTION_MOVE:
final float deltaY = ev.getY() - mLastMotionY;
mLastMotionY = ev.getY();
// deltaY = 0时,不重置mPullDown标志位,mPullDown标志位值沿用deltaY != 0时的状态值
if (deltaY != 0) {
mPullDown = deltaY > 0;
}
Log.d(TAG, "onTouchEvent,MotionEvent.ACTION_MOVE,deltaY = " + deltaY);
if (isPullRefreshEnabled() && isReadyForPullDown(deltaY)) {
// 处理头部滑动
Log.d(TAG, "onTouchEvent,MotionEvent.ACTION_MOVE,处理头部滑动");
pullHeaderLayout(deltaY / mOffsetRadio);
handled = true;
if (null != mFooterLayout && 0 != mFooterHeight) {
mFooterLayout.setState(IExtendLayout.State.RESET);
}
} else if (isPullLoadEnabled() && isReadyForPullUp(deltaY)) {
Log.d(TAG, "onTouchEvent,MotionEvent.ACTION_MOVE,处理底部滑动");
// 上拉
pullFooterLayout(deltaY / mOffsetRadio);
handled = true;
if (null != mHeaderLayout && 0 != mHeaderHeight) {
mHeaderLayout.setState(IExtendLayout.State.RESET);
}
} else {
mIsHandledTouchEvent = false;
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
Log.d(TAG, "onTouchEvent,MotionEvent.ACTION_UP");
// if (mIsHandledTouchEvent) {
// mIsHandledTouchEvent = false;
// 当第一个显示出来时
if (isReadyForPullDown(0)) {
Log.d(TAG, "onTouchEvent,MotionEvent.ACTION_UP,resetHeaderLayout");
if (mPullDown) {
// 弹性展开头部
resetHeaderLayout();
} else {
// 往上拉时,收缩头部,不弹性会弹
collapseHeaderLayout();
}
} else if (isReadyForPullUp(0)) {
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
如果您下载了本程序,但是该程序存在问题无法运行,那么您可以选择退款或者寻求我们的帮助(如果找我们帮助的话,是需要追加额外费用的)。另外,您不会使用资源的话(这种情况不支持退款),也可以找我们帮助(需要追加额外费用) 微信小程序是腾讯公司基于微信平台推出的一种轻量级应用形态,它无需用户下载安装即可在微信内直接使用。自2017年正式上线以来,小程序凭借其便捷性、易获取性和出色的用户体验迅速获得市场认可,并成为连接线上线下服务的重要桥梁。 小程序的核心特点包括: 零安装:用户只需通过微信扫一扫或搜索功能,即可打开和使用小程序,大大降低了用户的使用门槛和手机存储空间压力。 速度快:加载速度相较于传统的HTML5网页更快,依托于微信强大的基础设施,能够实现近乎原生应用的流畅体验。 跨平台兼容:开发者一次开发,即可在多种终端设备上运行,免除了复杂的适配工作,大大提高了开发效率。 社交属性强:小程序可以无缝嵌入微信生态,支持分享至聊天窗口、朋友圈等社交场景,有利于用户间的传播和裂变增长。 丰富接口能力:提供丰富的API接口,可调用微信支付、位置服务、用户身份识别等多种功能,方便企业进行商业服务的集成与拓展。 目前,微信小程序已经覆盖了电商购物、生活服务、娱乐休闲、教育学习、工具助手等多个领域,为数以亿计的用户提供便捷的服务入口,也为众多商家和开发者提供了新的商业模式和创业机会。随着技术的不断升级和完善,小程序已成为现代移动互联网生态中不可或缺的一部分。
资源推荐
资源详情
资源评论
收起资源包目录
仿微信小程序和QQ头部下拉展开更多布局.zip (69个子文件)
SJT-code
gradle.properties 728B
gradle
wrapper
gradle-wrapper.jar 53KB
gradle-wrapper.properties 232B
app
gif
yanshi.gif 930KB
src
androidTest
java
com
okg
pullloadmore
ExampleInstrumentedTest.java 724B
test
java
com
okg
pullloadmore
ExampleUnitTest.java 381B
main
java
com
okg
pullloadmore
adapter
ExtendHeadAdapter.java 975B
base
CommonAdapter.java 2KB
OnItemClickListener.java 166B
ViewHolder.java 1KB
MainContentAdapter.java 990B
helper
Validator.java 5KB
UIHelper.java 7KB
Htmls.java 388B
fragment
CopyQQHomeFragment.java 137B
CopyWeChatHomeFragment.java 141B
activity
MainActivity.java 3KB
view
pullextend
ExpendPoint.java 2KB
ExtendListFooter.java 3KB
IExtendLayout.java 1KB
IPullToExtend.java 1KB
PullExtendLayout.java 34KB
ExtendLayout.java 3KB
ExtendListHeader.java 4KB
App.java 408B
res
mipmap-xxhdpi
ic_launcher_round.png 10KB
ic_launcher.png 6KB
mipmap-hdpi
ic_launcher_round.png 5KB
ic_launcher.png 3KB
drawable-v24
ic_launcher_foreground.xml 2KB
mipmap-anydpi-v26
ic_launcher.xml 272B
ic_launcher_round.xml 272B
mipmap-mdpi
ic_launcher_round.png 3KB
ic_launcher.png 2KB
mipmap-xxxhdpi
ic_launcher_round.png 15KB
ic_launcher.png 9KB
mipmap-xhdpi
ic_launcher_round.png 7KB
ic_launcher.png 4KB
qq_logo.png 150KB
values
colors.xml 492B
strings.xml 90B
styles.xml 381B
layout
extend_header.xml 734B
item_header.xml 631B
item_home_chat.xml 2KB
extend_footer.xml 651B
activity_main.xml 1KB
drawable
ic_launcher_background.xml 5KB
btn_orange.xml 751B
btn_primary.xml 744B
AndroidManifest.xml 723B
proguard-rules.pro 751B
build.gradle 998B
.gitignore 7B
gradlew.bat 2KB
build.gradle 558B
.idea
dictionaries
oukanggui.xml 88B
codeStyles
Project.xml 1KB
dbnavigator.xml 22KB
runConfigurations.xml 564B
vcs.xml 180B
misc.xml 357B
inspectionProfiles
Project_Default.xml 1KB
gradle.xml 757B
encodings.xml 135B
settings.gradle 15B
gradlew 5KB
.gitignore 203B
README.md 8KB
共 69 条
- 1
资源评论
JJJ69
- 粉丝: 6351
- 资源: 5918
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功