
1、自定义控件
1、这里引用一个xml文件做为listview的headerView, LayoutInflater. inflate()的时候,注意最后的root为null,而不是this,以防 addHeaderView时出问题。
2、监听overScrollBy(),下拉过度时,放大mImageView。
3、监听onScrollChanged(),mImageView被放大了,且正在往上推时,缩小mImageView。
4、有一种特殊情况要注意:当放大后的mImageView.height+listview.height=屏幕高度时,再往上推时,会触发上拉过度,而不会调用 onScrollChanged中的缩小方法,此时需要处理下。
5、监听onTouchEvent(),松手后,开始恢复默认状态的动画。
package com.luocen_qqzone_overlistview;
import ndroid.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.ImageView;
import android.widget.ListView;
/**
* Description: 仿QQ空间可拉伸头部特效
* Author: zsk
* Date: 2018/2/2 14:18
* Email: zsk559521@163.com
*/
public class ParallaxListView extends ListView {
private ImageView mImageView;
private ImageView mHeaderImageView;
private int mImageViewHeight=0;
public ParallaxListView(Context context, AttributeSet attrs) {
super(context, attrs);
mImageViewHeight=context.getResources().getDimensionPixelSize(R.dimen.header_height);
}
//背景图片拉伸
public void setZoomImageView(ImageView iv){
mImageView=iv;
}
//头像旋转
public void setHeaderImageView(ImageView iv){
mHeaderImageView=iv;
}
/**
* 过度滑动
* <p>
* 注意:deltaX与deltaY与坐标系方向相反!!!
* @param deltaX 水平增量(-右拉过度,+左拉过度)
* @param deltaY 竖直增量(-下拉过度,+上拉过度)
**/
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
if(deltaY<0){ //下拉过度 对图片进行放大
mImageView.getLayoutParams().height=mImageView.getHeight()-deltaY;
mImageView.requestLayout();
//头像的旋转
mHeaderImageView.setRotation(mHeaderImageView.getRotation()-deltaY);
}else{//一种特殊情况:当放大后的mImageView.height+listview.height=屏幕高度时,再往上推时,会触发上拉过度,而不会调用onScrollChanged中的缩小方法
if(mImageView.getHeight()>mImageViewHeight) {
mImageView.getLayoutParams().height = mImageView.getHeight() - deltaY;
mImageView.requestLayout();
//头像的旋转
mHeaderImageView.setRotation(mHeaderImageView.getRotation()-deltaY);
}
}
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
//让ImageView上滑时缩小,监听
View header = (View) mImageView.getParent();
if(header.getTop()<0 && mImageView.getHeight()>mImageViewHeight){
//头像的旋转
mHeaderImageView.setRotation(mHeaderImageView.getRotation() + header.getTop());
mImageView.getLayoutParams().height=mImageView.getHeight()+header.getTop();
header.layout(header.getLeft(),0,header.getRight(),header.getHeight());
mImageView.requestLayout();
}
super.onScrollChanged(l, t, oldl, oldt);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
//监听松开手
int action = ev.getAction();
if(action==MotionEvent.ACTION_UP){
ResetAnimation resetAnimation=new ResetAnimation(mImageViewHeight);
resetAnimation.setDuration(300);
mImageView.startAnimation(resetAnimation);
}
return super.onTouchEvent(ev);
}
public class ResetAnimation extends Animation{
private int delay ; //高度差
private int currentHeight ; //当前的高度
private int mHeaderRotation; // 起始值
private int mHeaderDestRotation=0; //终止值
public ResetAnimation(int targetHeight){ //targetHeight 最终恢复的高度
delay = mImageView.getHeight() - targetHeight;
currentHeight = mImageView.getHeight();
mHeaderRotation= (int) mHeaderImageView.getRotation();
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
//interpolatedTime(0.0 to 1.0) 执行的百分比
//减小ImageView的高度
mImageView.getLayoutParams().height= (int) (currentHeight-delay*interpolatedTime);
mImageView.requestLayout();
//头像的旋转
int rotation= (int) (mHeaderRotation+(mHeaderDestRotation-mHeaderRotation)*interpolatedTime);
mHeaderImageView.setRotation(rotation);
super.applyTransformation(interpolatedTime, t);
}
}
}
2.控件的使用
package com.luocen_qqzone_overlistview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private ParallaxListView mListView;
private ImageView iv;
private ImageView iv_icon;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
View header=View.inflate(this,R.layout.header_view,null);
mListView=findViewById(R.id.lv);
iv=header.findViewById(R.id.iv_header);
iv_icon=header.findViewById(R.id.iv_icon);
ArrayAdapter<String> adapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1,
new String[]{
"星期一 去动脑学院上课",
"星期二 去有心课堂上课",
"星期三 去慕课网上课",
"星期四 去极客学院上课",
"星期五 去菜鸟教程上课",
"星期六 去泡在网上的日子上课",
"星期日 去Android开发中文站上课",
});
mListView.addHeaderView(header);
mListView.setZoomImageView(iv);
mListView.setHeaderImageView(iv_icon);
mListView.setAdapter(adapter);
}
}
3.依赖的资源:
R.layout.header_view:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_header"
android:layout_width="match_parent"
android:layout_height="@dimen/header_height"
android:scaleType="centerCrop"
android:src="@mipmap/love"/>
<ImageView
android:id="@+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/iv_header"
android:layout_margin="10dp"
android:scaleType="centerCrop"
android:src="@mipmap/ic_launcher_round"/>
</RelativeLayout>
R.layout.activity_main:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.luocen_qqzone_overlistview.ParallaxListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
项目源码地址:https://github.com/zhangshangkun/OverListView.git
仿QQ空间头部特效ListView
本文介绍了一种仿照QQ空间头部特效实现的ListView控件,通过自定义ListView实现下拉刷新时背景图片的拉伸效果及头像的旋转动画。文章详细解释了如何监听滑动事件并调整图片大小与头像角度。
713

被折叠的 条评论
为什么被折叠?



