android的阻尼效果

        很多时候我们在开发的过程中,需要做一些特殊的效果,今天就为大家介绍一下如何做一个阻尼的效果,所谓的阻尼效果就是头布局的背景图片在下拉的时候放大,在释放手指的时候缩小,从而产生放大缩小的效果。实现的方案就是继承ListView,并添加头布局,在触摸监听事件里面去实现该效果。下面就开始演示实现效果的效果图,以及代码的实现方式。
android的阻尼效果_第1张图片

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


<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


<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>

附:源码下载地址

你可能感兴趣的:(android)