很多时候我们在开发的过程中,需要做一些特殊的效果,今天就为大家介绍一下如何做一个阻尼的效果,所谓的阻尼效果就是头布局的背景图片在下拉的时候放大,在释放手指的时候缩小,从而产生放大缩小的效果。实现的方案就是继承ListView,并添加头布局,在触摸监听事件里面去实现该效果。下面就开始演示实现效果的效果图,以及代码的实现方式。
PullZoomListView.java
public class PullZoomListView extends ListView {
private LinearLayout mHeadView;//要实现阻尼效果的HeadView
private int mHeadViewHeight;//默认状态下要实现阻尼效果的HeadView的高度
private LayoutParams mParams;
private int mMaxHeight = 200;//自定义下拉增加的最大高度
private int mDownY = -1; // 按下的y轴的值, 默认为: -1
private int mDiffY = -1;//纪录最终下拉的高度,默认为: -1
public PullZoomListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initHeadView();
}
public PullZoomListView(Context context, AttributeSet attrs) {
super(context, attrs);
initHeadView();
}
public PullZoomListView(Context context) {
super(context);
initHeadView();
}
//给ListView的HeadView添加要实现阻尼效果的View
private void initHeadView() {
mHeadView = (LinearLayout) View.inflate(getContext(), R.layout.head_view, null);
mHeadView.measure(0, 0);// 手动测量宽高
mHeadViewHeight = mHeadView.getMeasuredHeight();
this.addHeaderView(mHeadView);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (isDisplayHeaderView()) {
mParams = (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;
mParams.height = mHeadViewHeight + mDiffY;
mHeadView.setLayoutParams(mParams);
}
}
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 arg0) {
Integer height = (Integer) arg0.getAnimatedValue();// 获取动画当前变化的值
// 根据最新高度,更新布局高度
mParams.height = height;
mHeadView.setLayoutParams(mParams);
}
});
animator.setDuration(50);// 动画时间
animator.start();// 开启动画
}
public View getView() {
return mHeadView;
}
/**
* 判断HeadView是否完全显示了.
*
* @return true, 完全显示, false 没有显示
*/
private boolean isDisplayHeaderView() {
int[] location = new int[2]; // 0位存储的是x轴的值, 1是y轴的值
// 获取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:orientation="vertical"
android:layout_height="match_parent"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/service_weather_pic_background" />
</RelativeLayout>
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
private PullZoomListView mListView;
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext=this;
initView();
}
//初始化View
private void initView(){
mListView=(PullZoomListView)findViewById(R.id.listView);
mListView.setAdapter(new Adapter());
}
private class Adapter extends BaseAdapter {
@Override
public int getCount() {
return 80;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(mContext);
textView.setPadding(50, 50, 50, 50);
textView.setText(position + 10 + "");
return textView;
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
>
<it.my.demo.view.PullZoomListView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="@+id/listView"
></it.my.demo.view.PullZoomListView>
</LinearLayout>