NestedScrollView嵌套RecycleView 滑动 实现上滑隐藏 下滑显示头部效果
废了好大的劲才弄好的,记下来 方便以后查看
- public class MainActivity extends AppCompatActivity {
- private RecyclerView mRecyclerView;
- private List<String> mDatas;
- private HomeAdapter mAdapter;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initData();
- mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview);
- //设置布局管理器
- mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
- //设置adapter
- mRecyclerView.setAdapter(mAdapter = new HomeAdapter());
- }
- protected void initData() {
- mDatas = new ArrayList<String>();
- for (int i = 'A'; i < 'z'; i++) {
- mDatas.add("" + (char) i);
- }
- }
- class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> {
- @Override
- public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- MyViewHolder holder = new MyViewHolder(LayoutInflater.from(
- MainActivity.this).inflate(R.layout.item_home, parent,
- false));
- return holder;
- }
- @Override
- public void onBindViewHolder(MyViewHolder holder, int position) {
- holder.tv.setText(mDatas.get(position));
- }
- @Override
- public int getItemCount() {
- return mDatas.size();
- }
- class MyViewHolder extends RecyclerView.ViewHolder {
- TextView tv;
- public MyViewHolder(View view) {
- super(view);
- tv = (TextView) view.findViewById(R.id.id_num);
- }
- }
- }
然后是最关键的NestedScrollview 是为了配合嵌套滑动的, NestedScrollview最关键有两个接口的实现 一个是 NestedScrollingChild 一个是NestedScrollingParent
先是NestedScrollingParent
- public class MyNestedScrollParent extends LinearLayout implements NestedScrollingParent {
- private String Tag = "MyNestedScrollParent";
- private View topView ;
- private View centerView;
- private View contentView;
- private MyNestedScrollChildL nsc ;
- private NestedScrollingParentHelper mParentHelper;
- private int imgHeight;
- private int tvHeight;
- private int mLastTouchY;
- public boolean topShow;
- public MyNestedScrollParent(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
- public MyNestedScrollParent(Context context) {
- super(context);
- init();
- }
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- topView = getChildAt(0);
- centerView = getChildAt(1);
- contentView = getChildAt(2);
- topView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- if(imgHeight<=0){
- imgHeight = topView.getMeasuredHeight();
- Log.i(Tag,"imgHeight:"+imgHeight+",tvHeight:"+tvHeight);
- }
- }
- });
- centerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- if(tvHeight<=0){
- tvHeight = centerView.getMeasuredHeight();
- Log.i(Tag,"imgHeight:"+imgHeight+",tvHeight:"+tvHeight);
- }
- }
- });
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
- {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- setMeasuredDimension(getMeasuredWidth(), topView.getMeasuredHeight() + centerView.getMeasuredHeight() + contentView.getMeasuredHeight());
- }
- public int getTopViewHeight(){
- Log.i(Tag,"getTopViewHeight--"+topView.getMeasuredHeight());
- return topView.getMeasuredHeight();
- }
- @Override
- public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
- Log.i(Tag,"onStartNestedScroll--"+"child:"+child+",target:"+target+",nestedScrollAxes:"+nestedScrollAxes);
- return true;
- }
- private void init() {
- mParentHelper = new NestedScrollingParentHelper(this);
- }
- @Override
- public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes) {
- Log.i(Tag,"onNestedScrollAccepted"+"child:"+child+",target:"+target+",nestedScrollAxes:"+nestedScrollAxes);
- mParentHelper.onNestedScrollAccepted(child, target, nestedScrollAxes);
- }
- @Override
- public void onStopNestedScroll(View target) {
- Log.i(Tag,"onStopNestedScroll--target:"+target);
- mParentHelper.onStopNestedScroll(target);
- }
- @Override
- public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
- Log.i(Tag,"onNestedScroll--"+"target:"+target+",dxConsumed"+dxConsumed+",dyConsumed:"+dyConsumed
- +",dxUnconsumed:"+dxUnconsumed+",dyUnconsumed:"+dyUnconsumed);
- }
- @Override
- public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
- if(showImg(dy)||hideImg(dy)){//如果父亲自己要滑动,则拦截
- consumed[1]=dy;
- scrollBy(0,dy);
- Log.i("onNestedPreScroll","Parent滑动:"+dy);
- }
- Log.i(Tag,"onNestedPreScroll--getScrollY():"+getScrollY()+",dx:"+dx+",dy:"+dy+",consumed:"+consumed);
- }
- @Override
- public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
- Log.i(Tag,"onNestedFling--target:"+target);
- return false;
- }
- @Override
- public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
- Log.i(Tag,"onNestedPreFling--target:"+target);
- return false;
- }
- @Override
- public int getNestedScrollAxes() {
- Log.i(Tag,"getNestedScrollAxes");
- return 0;
- }
- @Override
- public void scrollTo(int x, int y) {
- if(y<0){
- y=0;
- }
- if(y>imgHeight){
- y=imgHeight;
- }
- super.scrollTo(x, y);
- }
- /**
- 下拉的时候是否要向下滑动显示图片
- */
- public boolean showImg(int dy){
- if(dy<0){
- // if(getScrollY()>0&&nsc.getScrollY()==0){//如果parent外框,还可以往上滑动
- if(getScrollY()>0){
- return true;
- }
- }
- return false;
- }
- /**
- * 上拉的时候,是否要向上滑动,隐藏图片
- * @return
- */
- public boolean hideImg(int dy){
- if(dy>0){
- if(getScrollY()<imgHeight){//如果parent外框,还可以往下滑动
- return true;
- }
- }
- return false;
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if(event.getAction()==MotionEvent.ACTION_DOWN){
- return true;
- }
- return super.onTouchEvent(event);
- }
- @Override
- public boolean onInterceptTouchEvent(MotionEvent event) {
- return super.onInterceptTouchEvent(event);
- }
- @Override
- public boolean dispatchTouchEvent(MotionEvent event) {
- Log.i("aaa","getY():getRawY:"+event.getRawY());
- switch (event.getAction()){
- case MotionEvent.ACTION_DOWN:
- mLastTouchY = (int) (event.getRawY() + 0.5f);
- break;
- case MotionEvent.ACTION_MOVE:
- int y = (int) (event.getRawY() + 0.5f);
- int dy = mLastTouchY - y;
- mLastTouchY = y;
- if(showImg(dy)||hideImg(dy)){//如果父亲自己要滑动
- scrollBy(0,dy);
- }
- break;
- case MotionEvent.ACTION_UP:
- break;
- }
- return super.dispatchTouchEvent(event);
- }
- }
然后是NestedScrollingChild
- public class MyNestedScrollChild extends ScrollView implements NestedScrollingChild {
- private String Tag = "MyNestedScrollChild";
- private NestedScrollingChildHelper mScrollingChildHelper;
- public MyNestedScrollChild(Context context) {
- super(context);
- init(context);
- }
- public MyNestedScrollChild(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
- public MyNestedScrollChild(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init(context);
- }
- public void init(Context context) {
- final ViewConfiguration configuration = ViewConfiguration.get(context);
- }
- @Override
- public void setNestedScrollingEnabled(boolean enabled) {
- Log.i(Tag, "setNestedScrollingEnabled:" + enabled);
- getScrollingChildHelper().setNestedScrollingEnabled(enabled);
- }
- @Override
- public boolean isNestedScrollingEnabled() {
- Log.i(Tag, "isNestedScrollingEnabled");
- return getScrollingChildHelper().isNestedScrollingEnabled();
- }
- @Override
- public boolean startNestedScroll(int axes) {
- boolean bl = getScrollingChildHelper().startNestedScroll(axes);
- Log.i(Tag, "startNestedScroll:axes=" + axes + ",bl:" + bl);
- Log.i(Tag, "hasNestedScrollingParent=" + getScrollingChildHelper().hasNestedScrollingParent());
- return bl;
- }
- @Override
- public void stopNestedScroll() {
- Log.i(Tag, "stopNestedScroll");
- getScrollingChildHelper().stopNestedScroll();
- }
- @Override
- public boolean hasNestedScrollingParent() {
- Log.i(Tag, "hasNestedScrollingParent");
- return getScrollingChildHelper().hasNestedScrollingParent();
- }
- @Override
- public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
- int dyUnconsumed, int[] offsetInWindow) {
- Log.i(Tag, "dispatchNestedScroll:dxConsumed:" + dxConsumed + "," +
- "dyConsumed:" + dyConsumed + ",dxUnconsumed:" + dxUnconsumed + ",dyUnconsumed:" +
- dyUnconsumed + ",offsetInWindow:" + offsetInWindow);
- return getScrollingChildHelper().dispatchNestedScroll(dxConsumed, dyConsumed,
- dxUnconsumed, dyUnconsumed, offsetInWindow);
- }
- @Override
- public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
- Log.i(Tag, "dispatchNestedPreScroll:dx" + dx + ",dy:" + dy + ",consumed:" + consumed + ",offsetInWindow:" + offsetInWindow);
- return getScrollingChildHelper().dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
- }
- @Override
- public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
- Log.i(Tag, "dispatchNestedFling:velocityX:" + velocityX + ",velocityY:" + velocityY + ",consumed:" + consumed);
- return getScrollingChildHelper().dispatchNestedFling(velocityX, velocityY, consumed);
- }
- @Override
- public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
- Log.i(Tag, "dispatchNestedPreFling:velocityX:" + velocityX + ",velocityY:" + velocityY);
- return getScrollingChildHelper().dispatchNestedPreFling(velocityX, velocityY);
- }
- private NestedScrollingChildHelper getScrollingChildHelper() {
- if (mScrollingChildHelper == null) {
- mScrollingChildHelper = new NestedScrollingChildHelper(this);
- mScrollingChildHelper.setNestedScrollingEnabled(true);
- }
- return mScrollingChildHelper;
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- setMeasuredDimension(getMeasuredWidth(),getMeasuredHeight()+((MyNestedScrollParent)getParent()).getTopViewHeight());
- }
- }
- 布局文件
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="com.lmj.com.mynestscroll.MainActivity">
- <com.lmj.com.mynestscroll.view.MyNestedScrollParent
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#0f0"
- android:clickable="true"
- android:orientation="vertical">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- >
- <TextView
- android:id="@+id/tv_search"
- android:layout_width="match_parent"
- android:layout_height="100dp"
- android:gravity="center"
- android:padding="20dp"
- android:text="搜索" />
- <LinearLayout
- android:id="@+id/ll_other"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginLeft="20dp"
- android:layout_marginRight="20dp"
- android:orientation="vertical">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="#30ffffff"
- android:drawablePadding="10dp"
- android:gravity="center_vertical"
- android:padding="10dp"
- android:text="任何地方"
- android:textColor="#fff" />
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="10dp"
- android:background="#30ffffff"
- android:drawablePadding="10dp"
- android:padding="10dp"
- android:text="任何时间"
- android:textColor="#fff" />
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="10dp"
- android:background="#30ffffff"
- android:drawablePadding="10dp"
- android:padding="10dp"
- android:text="房客"
- android:textColor="#fff" />
- </LinearLayout>
- </LinearLayout>
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="#f0f"
- android:text="@string/topStr" />
- <com.lmj.com.mynestscroll.view.MyNestedScrollChild
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="1231231231312"
- />
- </com.lmj.com.mynestscroll.view.MyNestedScrollChild>
- <!--<com.lmj.com.mynestscroll.MyRecycleView-->
- <!--android:id="@+id/id_recyclerview"-->
- <!--android:layout_width="match_parent"-->
- <!--android:layout_height="match_parent">-->
- <!--</com.lmj.com.mynestscroll.MyRecycleView>-->
- </com.lmj.com.mynestscroll.view.MyNestedScrollParent>
- </RelativeLayout>
- NestedScrollingChild和NestedScrollingParent之间的部分,在滑动时会悬浮在顶部 而RecycleView 本身已经实现了NestedScrollingChild
- 我们在使用RecycleView的时候 需要重写onMeasure方法
- public class MyRecycleView extends RecyclerView {
- public MyRecycleView(Context context) {
- super(context);
- }
- public MyRecycleView(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
- public MyRecycleView(Context context, @Nullable AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- @Override
- protected void onMeasure(int widthSpec, int heightSpec) {
- super.onMeasure(widthSpec, heightSpec);
- setMeasuredDimension(getMeasuredWidth(),getMeasuredHeight()+((MyNestedScrollParent)getParent()).getTopViewHeight());
- }
- }
重新设定RecycleView的高度
NestedScrollView嵌套RecycleView 滑动 实现上滑隐藏 下滑显示头部效果的更多相关文章
- js监听事件 上滑消失下滑出现的效果 触摸与手势事件
https://www.w3cmm.com/javascript/touch.html //触摸与手势事件连接tinyscrollbar //方法1var _this = $('#fabu');var ...
- iOS 上滑隐藏导航,下滑显示导航,仿斗鱼导航效果
UItableView或 UIcollectionView 都是继承UIScrollView 滑动的时候,判断是上滑还是下滑 使用 UIScrollView 的代理方法 func scrollView ...
- NestedScrollView嵌套RecycleView发生的小问题
1.解决方法:嵌套滑动不激活. recycleView.setNestedScrollingEnable(false); 这样做有个弊端,RecycleView的item会一次性加载完,不管是否显示, ...
- uwp - 上滑隐藏导航栏下滑显示
原文:uwp - 上滑隐藏导航栏下滑显示 好久没写博客了,因为忙着工作.昨天周末填坑需要做一个上滑列表数据时隐藏导航栏下滑时显示的效果,下面分享一下我的做法,希望能给你带来帮助. 思路是通过判断滚动条 ...
- js判断手指的上滑,下滑,左滑,右滑,事件监听
原理:1:当开始一个touchstart事件的时候,获取此刻手指的横坐标startX和staerY: 2:当触发touchmove事件的时候,再获取此时手指的横坐标moveEndX和纵坐标moveEn ...
- vue中使用触摸事件,上滑,下滑,等
第一步,下载一个包 npm install kim-vue-touch -s 在当前项目中下载包 第二部 import vueTouch from 'kim-vue-touch' Vue.use(vu ...
- Android 浮动按钮+上滑隐藏按钮+下滑显示按钮
1.效果演示 1.1.关注这个红色的浮动按钮 . 可以看到,上滑的时候浮动按钮消失,因为用户迫切想知道下面的东西,而不是回到顶部. 当下滑的时候,用户想回到原来的位置,就可以点击浮动按钮,快速回到顶部 ...
- Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏ToolBar
ok,今天继续更新Material Design系列!!! 废话不说,先看看效果图吧: 好了,现在来讲讲上图是怎么实现的吧!讲之前先讲讲几个控件: CoordinatorLayout 该控件也是De ...
- iOS---实现简书和知乎的上滑隐藏导航栏下拉显示导航栏效果
因为自己用简书和知乎比较多,所以对其导航栏的效果比较好奇,自己私下里找资料实现了一下.这个效果的关键点在于下方可供滑动的内容的便宜距离inset的改变,以及滑动的scrollview代理的执行,废话不 ...
随机推荐
- mfc--使用ShellExecute打开另一个可执行程序
ShellExecute(sFile [, vArguments] [, vDirectory] [, vOperation] [, vShow]) ShellExecute(NULL,"o ...
- 网络服务器系统wamp的安装
第一步,下载wamp Server 可以百度查找下载,也可以到WAMP的官方网站http://wampserver.com/en下载,官网下载会比较慢. 第二步,下载之后,双击运行,安装 第三步,解压 ...
- Linux使用小笔记<安装篇>
问题一:在windows下删除ubuntu并修复引导windows启动. 1. 下载MBRFix工具,放在c盘,利用命令提示符,进入软件所在目录,cd c:\mbrfix 2.输入 MBRFix /d ...
- The Art of Prolog:Advanced Programming Techniques【译文】
申明:此文为译文,仅供学习交流试用,请勿用作商业用途,造成一切后果本人概不负责,转载请说明.本人英语功力尚浅,翻译大多借助于翻译工具,如有失误,欢迎指正. 逻辑程序简介 逻辑程序是一组公理或规则,定义 ...
- 使用python操作InfluxDB
环境: CentOS6.5_x64InfluxDB版本:1.1.0Python版本 : 2.6 准备工作 启动服务器 执行如下命令: service influxdb start 示例如下: [roo ...
- wemall app商城源码Fragment中监听onKey事件
wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享android开发Fragment中监听onK ...
- 获取3个月前的时间(获取某一天的时间 NSDate)
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; ...
- Python--校园网爬虫记
查成绩,算分数,每年的综合测评都是个固定的过程,作为软件开发者,这些过程当然可以交给代码去做,通过脚本进行网络请求获取数据,然后直接进行计算得到基础分直接填表就好了,查成绩再手动计算既容易出错也繁琐, ...
- ImportError: No module named cv2 解决方法
ImportError: No module named cv2 解决方法 import cv2时会出现这个问题 解决方法:将openCV安装目录里的python文件夹内的cv2.pyd复制到Py ...
- Freemaker配置文件详解
classic_compatible=true ##如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较 whitespace_stripping=true ...