仿百度动态Android源码,Android 仿百度手机助手首页滑动效果

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

1、当手指上划时,顶部搜索栏随手指移动距离而缩小到隐藏,隐藏后内容还是可以继续移动

2、手指下滑时,当显示内容达到第一个时,顶部搜索栏逐渐变大显示

自己实现用到的知识:

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

2、自定义viewgroup:测量view高度

额外添加的功能:

功能栏高度<=1/2时,会自动隐藏

功能栏高度>1/2时,会自动改变到最大值

代码实现在MotionEvent.ACTION_UP

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

869058761de90804d997c3a2d9b950c2.png

507faa575561efc52428f69d98dd3f24.png

本来想做成一个通用的工具类,工作比较忙就偷懒了,在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;

/**

* 滑动隐藏控件

*

*

*/

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

}

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android开源项目第一篇——个性化控件(View)篇 收藏的

Android开源项目第一篇——个性化控件(View)篇收藏的本文为那些不错的Android开源项目第一篇——个性化控件(View)篇,主要介绍Android上那些不错个性化的Vi

源码分析Fragmentd的BackStack管理过程

转载:http://blog.csdn.net/bigconvience/article/details/305020711.Fragment基本用法为了管理Activity中的fragments,需要调用Activity中的getFragmentManager()方法。因为FragmentMana

RecyclerView基本使用

RecyclerView是android5.0推出的新的控件,官方给出的说明是:RecyclerViewisamoreadvancedandflexibleversionofListView.Thiswidgetisacontainerforlargesetsofviewsthatcanberecycledandscrolle

项目名称:[精仿]360手机助手-14.2.6更新(CSkin Demo) 界面库版本号:14.2.6 最新版本 下载内容: 精仿360手机助手源码一份, 可引用至工具箱最新版CSkin.dll一份 实现功能: 1.发光标题。 2.直角边框和阴影。 3.360手机助手主界面模仿。 4.多系统支持,不需要win8系统,即可实现win8风格的360手机助手。 5.自定义控件的美化使用。 界面库更新文档: CC2014-2.6 1.修复拖动好友出现的负值BUG和拖动后有机率会消失的问题。 2.好友列表DoubleClickSubItem事件添加回调参数MouseEventArgs,用于判断鼠标操作的一些参数,如:左键双击还是右键双击判断。 3.对SkinDataGridView属性进行部分重构,颜色美化属性增加。 4.窗体加入绘制模式边框颜色属性BorderColor和InnerBorderColor 5.解决SkinTabControl left和right绘制模式下tab标签悬浮样式不变化问题。 6.所有控件采用最高质量模式绘制文字,防止字体模糊以及锯齿。 CC2013-12.8 1.优化SkinTabControl的效率,不再呢么闪烁,360DEMO直接替换DLL,改部分属性小错误,就可以看到明显闪烁减少效果。 2.为SkinStrip分类的控件添加 是否统一变换字体颜色的属性。 3.为SkinAnimatorImg动画图片框控件添加Stretch属性,是否拉伸模式绘制动画。 4.修复SkinComboBox无法DataSource绑定项的BUG。 5.增加音乐播放器,萝莉人物窗体,等DEMO。 6.修复部分细节bug。 提示:窗体继承SkinMain,再设置下SkinBack,有你想不到的惊喜哦,此窗体是用于绘制异形窗体专用,你给他什么图片,窗体就会按照图片来绘制。有一个缺点就是,有透明像素的背景区域,控件不给于显示。 CC2013-10.30 1.由于SkinForm名字太多人使用,界面库命名正式改为CSkin.dll,官网www.cskin.net。 2.SkinTabControl标签中添加菜单箭头,可点击展开菜单。 3.SkinTabControl添加标签关闭按钮。 4.修复部分中文乱码问题。 5.优化好友列表右键菜单。 6.将窗体自定义系统按钮改为集合模式,可添加无数个自定义系统按钮。自定义系统按钮事件中可以 e.参数 来判断。 7.增加360安全卫士-DEMO案例。 8.增加SkinAnimatorImg控件,用于支持位图动画的播放。如360的动态logo。 9.各种细节BUG优化。 CC2013-10.11 1.添加SkinTabControlEx,加入更加自定义的美化属性和动画效果。 2.添加SkinAnimator,通用动画控件。 3.添加Html编辑器控件 4.修复SkinButton图标和文本相对位置的BUG CC2013-9.26 1.优化好友列表CPU占用 2.好友列表加入好友登录平台属性:安卓 苹果 WEBQQ PC 3.优化标题绘制模式,新添标题绘制模式属性。 4.新添标题偏移度属性。 5.加入圆形进度条控件:ProgressIndicator。 CC2013-9.5.2 1.优化截图控件,截图工具栏加入新功能。 2.解决个人信息卡和天气窗体显示后不会消失的问题。 3.各种细节BUG优化。 CC2013-9.5.1 1.解决贴边左右隐藏的BUG。 2.解决窗体点击事件不能触发的问题。 3.优化SkinButton继承父容器背景色的代码。 4.解决SkinButton异常错误。 CC2013-9.3 1.好友列表右键菜单没反应问题。 2.新增美化控件SkinDatagridview。 3.密码软件盘回删不了文字问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值