仿NestedScrollingParent嵌套滑动
来源:互联网 发布:3g软件开发培训学校 编辑:程序博客网 时间:2024/05/14 15:27
用NestedScrollingParent很方便实现嵌套滑动,今天我们就用原始的套路自定义View来实现嵌套滑动功能,下次直接用NestedScrollingParent来实现。
先看下实现的效果:
先简单分析下思路:向上滑动时,当滑动高度没有超过头部的时候,滑动事件是被父类消费的,直到滑动的高度头超过头部的时候,滑动事件才传递给它的子view(这里是listview),此时选项按钮布局被固定在顶端。这时候listview可以自由滑动,当listview滑动到顶端不可再向下滑动时,滑动事件重新交给父类,头部View可滑动到之前的状态。
布局相关代码
<?xml version="1.0" encoding="utf-8"?><com.yq.nesting.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#ff00ff" > <RelativeLayout android:id="@+id/rl_headview" android:background="#033399" android:layout_width="match_parent" android:layout_height="200dp"> <TextView android:layout_centerInParent="true" android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="NESTING" android:textColor="#000000" android:textStyle="bold" /> </RelativeLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp"> <TextView android:gravity="center" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent" android:text="NESTING_1" android:background="#00ffff" /> <TextView android:gravity="center" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent" android:text="NESTING_2" android:background="#00ffff" /> <TextView android:gravity="center" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent" android:text="NESTING_3" android:background="#00ffff" /> </LinearLayout> <ListView android:background="#ffff00" android:layout_width="match_parent" android:id="@+id/listview" android:layout_height="match_parent"> </ListView></com.yq.nesting.MyLinearLayout>
自定view代码,里边有详细的注释
public class MyLinearLayout extends LinearLayout{ private Context mContext; public MyLinearLayout(Context context) { super(context); mContext = context; init(); } public MyLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; init(); } public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; init(); } private RelativeLayout rl_headview; private ListView listview; private int screenHeight,screenWidth; public void init(){ //获取屏幕信息 WindowManager wm = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); screenWidth = wm.getDefaultDisplay().getWidth(); screenHeight = wm.getDefaultDisplay().getHeight(); Log.e("screenHeight","screenHeight:"+screenHeight); } private int headViewHeight,listviewHeight,marginTop; @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); for (int i=0;i<this.getChildCount();i++){ measureChild(this.getChildAt(i),widthMeasureSpec,heightMeasureSpec); } rl_headview = (RelativeLayout)this.getChildAt(0); headViewHeight = rl_headview.getMeasuredHeight(); Log.e("headViewHeight","headViewHeight:"+headViewHeight); listview =(ListView)this.getChildAt(2); listviewHeight = listview.getMeasuredHeight(); Log.e("listviewHeight","listviewHeight:"+listviewHeight); //设置listview的高度,为了防止当头部View不见时,listview的高度没有填充整个页面 ViewGroup.LayoutParams myp = listview.getLayoutParams(); myp.height=screenHeight-this.getChildAt(1).getMeasuredHeight(); listview.setLayoutParams(myp); } @Override public boolean onTouchEvent(MotionEvent ev) { return super.onTouchEvent(ev); } private float delaY; private float scrollY; private float scrollInstanceY; @Override public boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_DOWN: scrollY = ev.getRawY(); break; case MotionEvent.ACTION_MOVE: delaY = scrollY -ev.getRawY(); scrollY = ev.getRawY(); if(delaY>0){ //向上滑时操作 scrollInstanceY = scrollInstanceY+delaY; Log.e("delaY","delaY:"+delaY+"----:"+scrollInstanceY); if(scrollInstanceY>headViewHeight){//当headview不可见是让选项布局停留在顶端 scrollInstanceY = headViewHeight; scrollTo(0,(int)scrollInstanceY); return super.dispatchTouchEvent(ev); }else if(scrollInstanceY<=headViewHeight){//滑动的距离没有超过headview的高度时 scrollTo(0,(int)scrollInstanceY); return true; } }else{ //向下滑时操作 Log.e("scrollInstanceY","scrollInstanceY:"+scrollInstanceY); Log.e("delaY----","delaY----:"+delaY); if(!isListViewTop()){ }else{ // 可以向下滑 scrollInstanceY = scrollInstanceY+delaY; if(scrollInstanceY<=0){//限制不能一直往下滑 scrollInstanceY = 0; } scrollTo(0,(int)scrollInstanceY); return true; } return super.dispatchTouchEvent(ev); } case MotionEvent.ACTION_UP: break; } return super.dispatchTouchEvent(ev); } //判断listview是否滑动到了顶部 public boolean isListViewTop(){ int fistVisiblePosition = listview.getFirstVisiblePosition(); if(fistVisiblePosition == 0&&getListViewScrollY()==0){ return true; } return false; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev); } //获得listview的滚动高度,只限每个item高度都一样 public int getListViewScrollY() { View c = listview.getChildAt(0); if (c == null) { return 0; } int firstVisiblePosition = listview.getFirstVisiblePosition(); int top = c.getTop(); Log.e("top","top:"+top); return -top + firstVisiblePosition * c.getHeight() ; }}
MainActivity代码
public class MainActivity extends Activity { private ListView listview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listview = (ListView)findViewById(R.id.listview); listview.setAdapter(new MyAdapter()); } public class MyAdapter extends BaseAdapter{ @Override public int getCount() { return 60; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { TextView tv = new TextView(MainActivity.this); tv.setText("我是第"+position+"条"); tv.setPadding(0,10,0,10); tv.setTextSize(25); return tv; } }}
0 0
- 仿NestedScrollingParent嵌套滑动
- 从NestedScrollingChild、NestedScrollingParent源码分析嵌套滑动机制
- Android-NestedScrollingParent, NestedScrollingChild父子View 间 的 嵌套滑动
- 实现嵌套滑动——NestedScrollingParent与NestedScrollingChild接口及其实现
- Android中NestedScrollingParent嵌套ListView
- NestedScrollingParent
- 仿网易云和支付宝首页嵌套滑动
- 对scrollview嵌套listview说不(二)NestedScrollingParent +RecyleView
- 滑动嵌套
- 使用FragmentTabHost实现仿QQ的切换,并在里面嵌套TabLayout+ViewPager的滑动切换
- 仿XP滑动菜单
- 仿QQ滑动删除
- 仿qq滑动删除
- 仿臭美app滑动
- 嵌套editview上下滑动
- Android 嵌套滑动分析
- android 嵌套滑动
- android嵌套滑动NestedScrolling
- 进程模型
- 浅谈Java异常处理机制
- 一道抽象向量组习题
- Git安装配置
- 【上】安全HTTPS-全面详解对称加密,非对称加密,数字签名,数字证书和HTTPS
- 仿NestedScrollingParent嵌套滑动
- 关于java文件编译后的JDK版本问题
- 数据双向绑定,邮箱格式验证,$scope作用域,过滤器
- 事务隔离机制原理分析以及是否可以防止订单超卖
- 自定义水波纹的View
- linux系统调用和库函数调用的区别
- 明文获取MD5加密文
- 《MySQL技术内幕——SQL编程》读书笔记(一)——SQL编程
- 【Lua】语法笔记#2