Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 仿百度手機助手首頁滑動效果

Android 仿百度手機助手首頁滑動效果

編輯:關於Android編程

今天看到百度手機助手首頁上的滑動效果非常nice,主要功能歸結為:

1、當手指上劃時,頂部搜索欄隨手指移動距離而縮小到隱藏,隱藏後內容還是可以繼續移動
2、手指下滑時,當顯示內容達到第一個時,頂部搜索欄逐漸變大顯示

自己實現用到的知識:

1、android事件傳遞機制:捕獲到手指移動事件後,根據移動的方向與功能欄的高度對功能欄大小進行修改 。由於listview與功能欄高度要同時移動,需要重寫了dispatchTouchEvent方法,直接調用this.onTouchEvent(ev);進行所有事件的捕捉分析
2、自定義viewgroup:測量view高度

額外添加的功能:

功能欄高度<=1/2時,會自動隱藏
功能欄高度>1/2時,會自動改變到最大值
代碼實現在MotionEvent.ACTION_UP

效果展示,錄像工具太卡,將就著看吧:
這裡寫圖片描述這裡寫圖片描述vc/Dpr7NzbXAwcHLo6zU2lNjcm9sbEhpZGVMYXlvdXTA4NbQtqjS5cHLwb249rOjwb+jrNaxvdPQtMvAwcvQ6NKqsbuytrvxu6y2r8rCvP7T67jEseS089ChtcR2aWV3SUSjrMq508PKsb/J0tTX1Ly61Nm0zrfi17CjrLvy1d/Wsb3T0N64xElEo6zL5Mi7srvNxrz2o6y1q8rHyqHKwrn+o6GjoaOhPC9wPg0KPGJsb2NrcXVvdGU+DQoJPHA+cHJpdmF0ZSBpbnQgc2Nyb2xsVmlld0lkID0gUi5pZC5zY3JvbGxWaWV3OyAvL7ustq+687Hku6+5psTcwLi1xHZpZXdpZDxiciAvPg0KCXByaXZhdGUgaW50IGNoYW5nZVZpZXdJZCA9IFIuaWQuY2hhbmdlVmlldzsvLyC089Chy+bWrrHku6+1xHZpZXdpZDwvcD4NCjwvYmxvY2txdW90ZT4NCjxwPs3q1fu0+sLro7o8YnIgLz4NCjGhotfUtqjS5bXEdmlld2dyb3VwPC9wPg0KPHByZSBjbGFzcz0="brush:java;"> 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; /** * 滑動隱藏控件 * * */ public class ScrollHideLayout extends LinearLayout implements OnScrollListener { private static final 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); } @Override protected void onMeasure(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); } } private void setScrollViewRect() { // 獲取滾動控件的范圍 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; } @Override public boolean onTouchEvent(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() { @Override public void onAnimationUpdate(ValueAnimator animation) { int value = (int) animation.getAnimatedValue(); params.height = value; changeView.requestLayout(); } }); anim.setDuration(250); anim.setTarget(changeView); anim.start(); } break; } return true; } @Override public boolean dispatchTouchEvent(MotionEvent ev) { // 直接攔截事件 this.onTouchEvent(ev); return super.dispatchTouchEvent(ev); } private boolean isScrollViewTouch(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. */ public boolean canChildScrollUp() { 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); } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // TODO Auto-generated method stub } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // TODO Auto-generated method stub } }

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved