转载:android的阻尼效果
package com.xiey94.zuni;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.LinearLayout;
import android.widget.ListView;
/**
* @author xiey
* @date created at 2017/12/6 20:34
* @package com.xiey94.zuni
* @motto Why should our days leave us never to return?
*/
public class PullZoomListView extends ListView {
/**
* 要实现阻尼效果的HeadView
*/
private LinearLayout mHeadView;
/**
* 默认状态下要实现阻尼效果的HeadView
*/
private int mHeadViewHeight;
private AbsListView.LayoutParams params;
/**
* 自定义下拉增加的最大高度
*/
private int mMaxHeight = 200;
/**
* 按下的y轴的值,默认为 :-1
*/
private int mDownY = -1;
/**
* 记录最终下拉的高度,默认为:-1
*/
private int mDiffY = -1;
/**
* 构造函数
*/
public PullZoomListView(Context context, AttributeSet attrs) {
super(context, attrs);
initHeadView();
}
/**
* 给ListView的HeadView添加要实现阻尼效果的View
*/
private void initHeadView() {
mHeadView = (LinearLayout) View.inflate(getContext(), R.layout.head_view, null);
//手动测量宽高,最终是UNSPECIFIED :模式下父容器不会对子元素加以任何约束,直接是图片的大小
mHeadView.measure(0, 0);
mHeadViewHeight = mHeadView.getMeasuredHeight();
Log.e("TAG", "measureHeight:" + mHeadViewHeight);
this.addHeaderView(mHeadView);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (isDisplayHeaderView()) {
params = (AbsListView.LayoutParams) mHeadView.getLayoutParams();
mDownY = (int) ev.getY();
}
break;
case MotionEvent.ACTION_MOVE:
if (isDisplayHeaderView()) {
if (mDownY == -1) {
mDownY = (int) ev.getY();
}
int moveY = (int) ev.getY();
//移动的间距
int diffY = moveY - mDownY;
if (diffY >= mMaxHeight) {
diffY = mMaxHeight;
}
if (diffY > 0) {
mDiffY = diffY;
params.height = mHeadViewHeight + mDiffY;
mHeadView.setLayoutParams(params);
}
}
break;
case MotionEvent.ACTION_UP:
if (mDiffY > 0 && isDisplayHeaderView()) {
reset();
}
break;
default:
break;
}
return super.onTouchEvent(ev);
}
/**
* 释放手指后实现阻尼效果
*/
private void reset() {
// mDiffY = -1;
//动画器
ValueAnimator animator;
//动画更新的监听
animator = ValueAnimator.ofInt(mHeadViewHeight + mDiffY, mHeadViewHeight);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//获取动画当前变化的值
Integer height = (Integer) animation.getAnimatedValue();
//根据最新高度,更新布局高度
params.height = height;
mHeadView.setLayoutParams(params);
}
});
//动画时间
animator.setDuration(50);
//开启动画
animator.start();
}
public View getView() {
return mHeadView;
}
/**
* 判断HeadView是否完全显示了
* true完全显示,false没有显示
*/
private boolean isDisplayHeaderView() {
//0存储x,1存储y
int[] location = new int[2];
//获取HeadView屏幕中y轴的值
mHeadView.getLocationOnScreen(location);
int mSecondHeaderViewYOnScreen = location[1];
return mSecondHeaderViewYOnScreen > 0 ? true : false;
}
}
head_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@drawable/huge_min" />
</RelativeLayout>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PullZoomListView listView = (PullZoomListView) findViewById(R.id.listView);
List<String> data = new ArrayList<>();
for (int i = 0; i < 30; i++) {
data.add("嘻嘻哈哈哈AKD");
}
listView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, data));
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.xiey94.zuni.PullZoomListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
这里要注意一下:
mHeadView.measure(0, 0);
最后附赠上胡歌的帅照: