头部视觉视差(仿QQ控件下拉效果)

看到新版QQ空间出来的时候,首页的下拉的效果比较炫酷,下拉的时候会把整张图片显示出来,松开手之后就会自己恢复原状,不说了,上代码。

这是效果图


public class ParallaxListView extends ListView {
//关于自定义控件
//onmeasure->onlayout->ondraw这是调用顺序(也就是先测量,再摆放空间的位置,最后再把控件画出来)
private int maxHeight;
private int orignalHeight;


public ParallaxListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


public ParallaxListView(Context context, AttributeSet attrs) {
super(context, attrs);
}


public ParallaxListView(Context context) {
super(context);
}
private ImageView imageView;
public void setParallaxImageView(final ImageView imageView){
this.imageView=imageView;

//设置最大高度
imageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {



@Override
public void onGlobalLayout() {
imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
orignalHeight = imageView.getHeight();
int drawableHeight = imageView.getDrawable().getIntrinsicHeight();

maxHeight=orignalHeight>drawableHeight?orignalHeight*2:drawableHeight;//获取图片的高度
}
});

}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction()==MotionEvent.ACTION_UP) {
//恢复最初高度
ValueAnimator amAnimator=ValueAnimator.ofInt(imageView.getHeight(),orignalHeight);
amAnimator.addUpdateListener(new AnimatorUpdateListener() {

@Override
public void onAnimationUpdate(ValueAnimator animator) {
//获取动画的值,设置给imageview
int animatedValue = (int) animator.getAnimatedValue();
imageView.getLayoutParams().height=animatedValue;
imageView.requestLayout();//imageview的布局参数生效
}
});
amAnimator.setInterpolator(new OvershootInterpolator());//弹性插补器
//这和插补器其实就是一个函数详细可以参考这个网址http://www.2cto.com/kf/201306/222725.html
amAnimator.setDuration(350);
amAnimator.start();
}
return super.onTouchEvent(ev);
}
/**
* listview滑动到头的时候执行,可以获得listview 的滑动距离和方向
* deltaX:继续滑动x方向的距离
* deltaY:继续滑动y方向的距离
* maxOverScrollX:x方向最大滚动的距离
* isTouchEvent:是否 是手指拖动滑动true手指滑动 false:fling滑动,惯性滑动
*/
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
if (imageView!=null) {
if (deltaY<0&&isTouchEvent) {
//表示顶部到头,并且是手动到头
//需要不断增加imageview的高度
int newHeight=imageView.getHeight()-deltaY;
if (newHeight>maxHeight) {
newHeight=maxHeight;
}
imageView.getLayoutParams().height=newHeight;
imageView.requestLayout();//imageview的布局参数生效
}
}

return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}

}

首先是布局代码activity_main

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     >


   <com.example.headerparallax.ParallaxListView
       android:id="@+id/listview"
       android:layout_width="match_parent"
    android:layout_height="match_parent"
       >
       
   </com.example.headerparallax.ParallaxListView>


</RelativeLayout>

布局没什么好说的就是自定义了一个listview。



java代码MainActivity 

package com.example.headerparallax;


import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;


public class MainActivity extends Activity {


private ParallaxListView listView;
private String[] indexArr = { "A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z" };
private ImageView imageView;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ParallaxListView) findViewById(R.id.listview);
listView.setOverScrollMode(ListView.OVER_SCROLL_NEVER);//永远不显示蓝色阴影
// 添加header布局
View headerView = View.inflate(this, R.layout.layout_header, null);
imageView = (ImageView) headerView.findViewById(R.id.imageview);
listView.setParallaxImageView(imageView);
listView.addHeaderView(headerView);
listView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, indexArr));

}
}

这个activity用的是一个ArrayAdapter,比较简单,为了方便就没有自定义适配器。

接下来的就是重点了,

自定义的listview也就是ParallaxListView

public class ParallaxListView extends ListView {
//关于自定义控件
//onmeasure->onlayout->ondraw这是调用顺序(也就是先测量,再摆放空间的位置,最后再把控件画出来)
private int maxHeight;
private int orignalHeight;


public ParallaxListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


public ParallaxListView(Context context, AttributeSet attrs) {
super(context, attrs);
}


public ParallaxListView(Context context) {
super(context);
}
private ImageView imageView;
public void setParallaxImageView(final ImageView imageView){
this.imageView=imageView;

//设置最大高度
imageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {



@Override
public void onGlobalLayout() {
imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
orignalHeight = imageView.getHeight();
int drawableHeight = imageView.getDrawable().getIntrinsicHeight();

maxHeight=orignalHeight>drawableHeight?orignalHeight*2:drawableHeight;//获取图片的高度
}
});

}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction()==MotionEvent.ACTION_UP) {
//恢复最初高度
ValueAnimator amAnimator=ValueAnimator.ofInt(imageView.getHeight(),orignalHeight);
amAnimator.addUpdateListener(new AnimatorUpdateListener() {

@Override
public void onAnimationUpdate(ValueAnimator animator) {
//获取动画的值,设置给imageview
int animatedValue = (int) animator.getAnimatedValue();
imageView.getLayoutParams().height=animatedValue;
imageView.requestLayout();//imageview的布局参数生效
}
});
amAnimator.setInterpolator(new OvershootInterpolator());//弹性插补器
//这和插补器其实就是一个函数详细可以参考这个网址http://www.2cto.com/kf/201306/222725.html
amAnimator.setDuration(350);
amAnimator.start();
}
return super.onTouchEvent(ev);
}
/**
* listview滑动到头的时候执行,可以获得listview 的滑动距离和方向
* deltaX:继续滑动x方向的距离
* deltaY:继续滑动y方向的距离
* maxOverScrollX:x方向最大滚动的距离
* isTouchEvent:是否 是手指拖动滑动true手指滑动 false:fling滑动,惯性滑动
*/
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
if (imageView!=null) {
if (deltaY<0&&isTouchEvent) {
//表示顶部到头,并且是手动到头
//需要不断增加imageview的高度
int newHeight=imageView.getHeight()-deltaY;
if (newHeight>maxHeight) {
newHeight=maxHeight;
}
imageView.getLayoutParams().height=newHeight;
imageView.requestLayout();//imageview的布局参数生效
}
}

return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}

}

最后,希望可以对你们有所帮助!

下载链接:http://download.csdn.net/detail/qq_32673327/9584545





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值