Android_滑动的时候头部变化效果
来源:互联网 发布:mac口红市场占有率 编辑:程序博客网 时间:2024/04/30 09:07
废话少说,直接上图哦
先看看上面的布局,从上到下:头部使用相对布局,然后是三个选项,然后线性布局里面装的fragment,fragment里面又是可以上啦刷新的listview。我的思路是准备在activity里面直接实现。activtiy里面有两个处理事件的方法
onTouchEvent(MotionEvent event)
dispatchTouchEvent(MotionEvent ev)
这两个事件选哪个合适呢?肯定是选第二个赛,选第一个的话肯定实现不起效果,因为事件传递(不懂百度),就被listview消耗了。
下面进入正题:
第一步:滚动的时候试着改变头部的高度
第二步:逐渐让周围不需要的字体消失
第三步:根据偏移率计算偏移量,然后把图片和需要的文字移动到顶端中心处
先声明需要用到的数据,下面全部列举出来
private int mLastY = 0; //最后的点private static int mNeedDistance; // 需要滑动的距离private static int mMinHight; //最小高度private static int mOrignHight; //原始的高度private int mCurrentDistance = 0; //当前的距离private float mRate = 0; //距离与目标距离的变化率 mRate=mCurrentDistance/mNeedDistanceprivate int mPhotoOriginHeight; //图片的原始高度private int mPhotoOriginWidth; //图片的原始宽度private int mPhotoLeft; //图片距左边的距离private int mPhotoTop; //图片距离上边的距离private int mPhotoNeedMoveDistanceX; // 图片需要移动的X距离private int mPhotoNeedMoveDistanceY; // 图片需要移动的Y距离//需要移动的文字private int mTextLeft; //文字距左边的距离private int mTextTop; //文字距离上边的距离private int mTextNeedMoveDistanceX; // 文字需要移动的X距离private int mTextNeedMoveDistanceY; //文字需要移动的Y距离/** * 初始化需要滚动的距离 */private void initDistance() { mOrignHight = rl_head.getLayoutParams().height; mMinHight = UIUtils.dip2px(this, 45); //设置最小的高度为这么多 mNeedDistance = mOrignHight - mMinHight; RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) img_head_portrait.getLayoutParams(); mPhotoOriginHeight = params.height; mPhotoOriginWidth = params.width; mPhotoLeft = params.leftMargin; mPhotoTop = params.topMargin; mPhotoNeedMoveDistanceX = UIUtils.getWindowWidth(this) / 2 - mPhotoLeft - mMinHight; mPhotoNeedMoveDistanceY = mPhotoTop - UIUtils.dip2px(this, 10); /*******************移动的文字初始化***************************/ RelativeLayout.LayoutParams textParams = (RelativeLayout.LayoutParams) tv_user_name.getLayoutParams(); mTextLeft = textParams.leftMargin; mTextTop = textParams.topMargin; mTextNeedMoveDistanceX = UIUtils.getWindowWidth(this) / 2 - mTextLeft + 10; mTextNeedMoveDistanceY = mTextTop - mMinHight / 2 / 2; //这里计算有点误差,正确的应该是剪去获取textview高度的一半}
实现第一步操作:
@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mLastY = (int) ev.getY(); LogUtils.d(TAG, "ACTION_MOVE==mCurrentDistance" + mCurrentDistance); return super.dispatchTouchEvent(ev); //传递事件 例如可以用来子view的点击事件等 case MotionEvent.ACTION_MOVE: int y = (int) ev.getY(); int dy = mLastY - y; LogUtils.d(TAG, "ACTION_MOVE==mCurrentDistance" + mCurrentDistance); if (mCurrentDistance >= mNeedDistance && dy > 0) { return super.dispatchTouchEvent(ev); //传递事件 } if (mCurrentDistance <= 0 && dy < 0) { return super.dispatchTouchEvent(ev); //把事件传递进去 } //改变布局 changeTheLayout(dy); mLastY = y; break; case MotionEvent.ACTION_UP: checkTheHeight(); LogUtils.d(TAG, "ACTION_MOVE==mCurrentDistance" + mCurrentDistance); return super.dispatchTouchEvent(ev); } return false;}
改变布局的大小的:
/** * 通过滑动的偏移量 * * @param dy */private void changeTheLayout(int dy) { final ViewGroup.LayoutParams layoutParams = rl_head.getLayoutParams(); layoutParams.height = layoutParams.height - dy; rl_head.setLayoutParams(layoutParams); checkTheHeight(); rl_head.requestLayout(); //计算当前移动了多少距离 mCurrentDistance = mOrignHight - rl_head.getLayoutParams().height; mRate = (float) (mCurrentDistance * 1.0 / mNeedDistance); changeTheAlphaAndPostion(mRate); //获取偏移率然后改变某些控件的透明度,和位置 LogUtils.d(TAG, "ACTION_MOVE==dy" + dy);}
获取了偏移率(0.0-1.0),然后就可以根据这个改变透明度了和大小了。
/** * 根据变化率来改变这些这些控件的变化率位置 * * @param rate */private void changeTheAlphaAndPostion(float rate) { //先改变一些控件的透明度 if (rate >= 1) { tv_user_hosipital.setVisibility(View.GONE); tv_user_hosipital_level.setVisibility(View.GONE); tv_user_project.setVisibility(View.GONE); } else { tv_user_hosipital.setVisibility(View.VISIBLE); tv_user_hosipital_level.setVisibility(View.VISIBLE); tv_user_project.setVisibility(View.VISIBLE); tv_user_hosipital.setAlpha(1 - rate); tv_user_hosipital_level.setAlpha(1 - rate); tv_user_project.setAlpha(1 - rate); tv_user_hosipital.setScaleY(1 - rate); tv_user_hosipital.setScaleX(1 - rate); tv_user_hosipital_level.setScaleY(1 - rate); tv_user_hosipital_level.setScaleX(1 - rate); tv_user_project.setScaleY(1 - rate); tv_user_project.setScaleX(1 - rate); } //接下来是改变控件的大小和位置了 (这就是关键了) final RelativeLayout.LayoutParams photoParams = (RelativeLayout.LayoutParams) img_head_portrait.getLayoutParams(); photoParams.width = (int) (mPhotoOriginWidth - (rate * (mPhotoOriginWidth - mMinHight - UIUtils.dip2px(this, 10)))); photoParams.height = (int) (mPhotoOriginWidth - (rate * (mPhotoOriginWidth - mMinHight - UIUtils.dip2px(this, 10)))); photoParams.leftMargin = (int) (mPhotoLeft + mPhotoNeedMoveDistanceX * rate); photoParams.topMargin = (int) (mPhotoTop - mPhotoNeedMoveDistanceY * rate); LogUtils.d(TAG, "photoParams.leftMargin" + photoParams.leftMargin); LogUtils.d(TAG, " photoParams.topMargin" + photoParams.topMargin); img_head_portrait.setLayoutParams(photoParams); /*********************文字设置****************************/ final RelativeLayout.LayoutParams textParams = (RelativeLayout.LayoutParams) tv_user_name.getLayoutParams(); textParams.leftMargin = (int) (mTextLeft + mTextNeedMoveDistanceX * rate); textParams.topMargin = (int) (mTextTop - mTextNeedMoveDistanceY * rate); LogUtils.d(TAG, "textParams.leftMargin" + textParams.leftMargin); LogUtils.d(TAG, " textParams.topMargin" + textParams.topMargin); tv_user_name.setLayoutParams(textParams);}
卧槽,搞忘了一个方法,滑动的时候需要检查边界值;这里写了一个方法:
/** * 检查上边界和下边界 */private void checkTheHeight() { final ViewGroup.LayoutParams layoutParams = rl_head.getLayoutParams(); if (layoutParams.height < mMinHight) { layoutParams.height = mMinHight; rl_head.setLayoutParams(layoutParams); rl_head.requestLayout(); } if (layoutParams.height > mOrignHight) { layoutParams.height = mOrignHight; rl_head.setLayoutParams(layoutParams); rl_head.requestLayout(); }}
还有一个关键的地方,布局文件的时候 最好是图片控件和需要移动的文字textview不要依赖于其他控件,不然计算margin很麻烦,所以我布局文件就用了简单粗糙的来实现布局:
需要变化的图片控件
<com.facebook.drawee.view.SimpleDraweeView android:id="@+id/img_head_portrait" android:layout_width="90dp" android:layout_height="90dp" android:layout_centerVertical="true" android:layout_marginLeft="@dimen/margin_20dp" android:padding="1dp" fresco:fadeDuration="500" fresco:placeholderImage="@mipmap/icon_user_avatar" />
需要变化的文字控件
<TextView android:id="@+id/tv_user_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="120dp" //这个距离直接设置的 ,不要用align。。。这个属性,不然不好计算margin android:layout_marginTop="@dimen/margin_30dp" //这个也是一样的道理 android:text="蒋心平" android:textColor="@color/white" android:textSize="@dimen/text_size_18" />
差不多就这样就能实现上面的效果了。当做完这个功能的时候,我突然觉得一些主流app,实现的向上滑动,title慢慢消失或者隐藏就so easy了,原理都是一样的。只要对事件分发拦截机制有一点认识都能实现这样的效果了。
6 0
- Android_滑动的时候头部变化效果
- Android_滑动的时候头部变化效果
- Android 微博头条头部滑动的效果
- tableview下拉的时候,头部图片放大效果view下拉的时候,头部图片放大效果
- Android滑动改变头部效果
- android_如何巧妙在Listview滑动时将头部固定
- Android ListView 滑动的时候数据消失变化
- android_手势滑动的实现
- Android -- 仿微信滑动,底部图片和字体变化的效果
- Android_自定义HorizontalScrollView实现滑动子控件大小变化动画
- 上滑动改变头部,仿支付宝头部变化,解决ScrollView与listView冲突问题
- UICollectionView的头部悬停效果
- ColorAnimationView 实现了滑动Viewpager 时背景色动态变化的过渡效果
- 移动端页面上下滑动,大小、透明度的变化视觉差异效果切换页面
- ViewPager+Fragment+TabLayout实现的头部滑动
- android_实现EditText的抖动效果
- Android_不同行为的Fragement的生命周期的变化
- LinearSnapHelper , 滑动停靠效果, 当滑动停止的时候,自动调整item,左对齐,或者靠中对齐
- hadoop伪分布环境配置以及hbase 配置
- 将Echarts的图形保存为图片
- 红茶一杯话Binder
- Shiro学习(20)无状态Web应用集成
- Linux source --重新执行刚修改的初始化文件
- Android_滑动的时候头部变化效果
- 机器学习和计算机视觉有关的数学
- ZT213LEEA.PDF_CSDN下载
- DateFormatUtils 时间工具类
- [IOS 开发] 获取设备UUID
- 多线程
- Linux sync --强制将内存中的文件缓冲内容写到磁盘
- Android基础空间spinner
- 开源图片加载工具Fresco使用详解