Android 仿百度手机助手首页滑动效果

今天看到百度手机助手首页上的滑动效果非常nice,主要功能归结为:

1、当手指上划时,顶部搜索栏随手指移动距离而缩小到隐藏,隐藏后内容还是可以继续移动 2、手指下滑时,当显示内容达到第一个时,顶部搜索栏逐渐变大显示

自己实现用到的知识:

1、android事件传递机制:捕获到手指移动事件后,根据移动的方向与功能栏的高度对功能栏大小进行修改 。由于listview与功能栏高度要同时移动,需要重写了dispatchTouchEvent方法,直接调用this.onTouchEvent(ev);进行所有事件的捕捉分析 2、自定义viewgroup:测量view高度

额外添加的功能:

功能栏高度<=1/2时,会自动隐藏 功能栏高度>1/2时,会自动改变到最大值 代码实现在MotionEvent.ACTION_UP

效果展示,录像工具太卡,将就着看吧:

本来想做成一个通用的工具类,工作比较忙就偷懒了,在ScrollHideLayout类中定义了两个常量,直接写死了需要被捕获滑动事件与改变大小的viewID,使用时可以自己再次封装,,或者直接修改ID,虽然不推荐,但是省事哈!!!

private int scrollViewId = R.id.scrollView; //滑动后变化功能栏的viewid private int changeViewId = R.id.changeView;// 大小随之变化的viewid

完整代码: 1、自定义的viewgroup

package com.example.materialtest.widget;import android.animation.ObjectAnimator;import android.animation.ValueAnimator;import android.animation.ValueAnimator.AnimatorUpdateListener;import android.content.Context;import android.graphics.PointF;import android.graphics.RectF;import android.support.v4.view.ViewCompat;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import android.widget.LinearLayout;import com.example.materialtest.R;/** * 滑动隐藏控件 * * */{String TAG = ScrollHideLayout.class.getSimpleName();private int scrollViewId = R.id.scrollView;private int changeViewId = R.id.changeView;private int changeViewMaxHeight;private PointF touchPoint = new PointF();private View changeView;private AbsListView scrollView;private RectF scrollViewRect = new RectF();public ScrollHideLayout(Context context, AttributeSet attrs) {this(context, attrs, 0);}public ScrollHideLayout(Context context) {this(context, null);}public ScrollHideLayout(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int len = getChildCount();if (null == changeView || null == scrollView) {for (int i = 0; i < len; i++) {View child = getChildAt(i);// 滑动控件if (child.getId() == scrollViewId && child instanceof AbsListView) {scrollView = (AbsListView) child;setScrollViewRect();}if (child.getId() == changeViewId) {changeView = child;changeView.setMinimumHeight(0);changeViewMaxHeight = changeView.getMeasuredHeight();}}} else {// 重新计算滚动控件的位置setScrollViewRect();}Log.i(TAG, “find scrollview and changeView :” + scrollViewId + “,” + changeViewId);Log.i(TAG, “scrollview rect:” + changeView.getLayoutParams().getClass().getCanonicalName());if (null == changeView || null == scrollView) {throw new IllegalArgumentException(“could not foud changeView or scrollView”);}}() {// 获取滚动控件的范围float left = ViewCompat.getX(scrollView);float top = ViewCompat.getY(scrollView);float right = left + scrollView.getMeasuredWidth();float bottom = top + scrollView.getMeasuredHeight();scrollViewRect.left = left;scrollViewRect.top = top;scrollViewRect.right = right;scrollViewRect.bottom = bottom;}(MotionEvent ev) {if (!isScrollViewTouch(ev)) {return false;}final android.view.ViewGroup.LayoutParams params = changeView.getLayoutParams();switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:touchPoint.x = ev.getX();touchPoint.y = ev.getY();break;case MotionEvent.ACTION_MOVE:int height = params.height;// 滑动控件移动事件float distance = ev.getY() – touchPoint.y;// 最大高度,不能向下拖动if (height >= changeViewMaxHeight && distance > 0) {touchPoint.y = ev.getY();break;}// 已经隐藏 不能向上滑动if (height <= 0 && distance < 0) {touchPoint.y = ev.getY();break;}// listview到达顶部才可以向下拖动if (distance > 0 && scrollView.getFirstVisiblePosition() != 0) {touchPoint.y = ev.getY();break;}height = Math.round(height + distance);if (height > changeViewMaxHeight) {height = changeViewMaxHeight;}if (height <= 0 && distance < 0) {height = 0;// TODO onhide}params.height = height;changeView.requestLayout();touchPoint.x = ev.getX();touchPoint.y = ev.getY();break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:// 高度超过一半,自动隐藏int[] values = null;// 向上滑动,剩余位置不足一半if (params.height <= changeViewMaxHeight / 2) {values = new int[] { params.height, 0 };} else {values = new int[] { params.height, changeViewMaxHeight };}if (null != values) {ValueAnimator anim = ObjectAnimator.ofInt(changeView, “translationY”, values);anim.addUpdateListener(new AnimatorUpdateListener() {(ValueAnimator animation) {int value = (int) animation.getAnimatedValue();params.height = value;changeView.requestLayout();}});anim.setDuration(250);anim.setTarget(changeView);anim.start();}break;}return true;}(MotionEvent ev) {// 直接拦截事件this.onTouchEvent(ev);return super.dispatchTouchEvent(ev);}(MotionEvent ev) {float x = ev.getX();float y = ev.getY();return (x >= scrollViewRect.left && x <= scrollViewRect.right) && (y >= scrollViewRect.top && y <= scrollViewRect.bottom);}/*** @return Whether it is possible for the child view of this layout to*scroll up. Override this if the child view is a custom view.*/() {if (android.os.Build.VERSION.SDK_INT < 14) {if (scrollView instanceof AbsListView) {final AbsListView absListView = (AbsListView) scrollView;return absListView.getChildCount() > 0&& (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0).getTop() < absListView.getPaddingTop());} else {return ViewCompat.canScrollVertically(scrollView, -1) || scrollView.getScrollY() > 0;}} else {return ViewCompat.canScrollVertically(scrollView, -1);}}(AbsListView view, int scrollState) {// TODO Auto-generated method stub}(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {// TODO Auto-generated method stub}}

不要忘本,任何时候,任何事情。

Android 仿百度手机助手首页滑动效果

相关文章:

你感兴趣的文章:

标签云: