看到新版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