让Activity UI普通控件具有弹性效果(一)

一、定义监听器

package test.xzy.com.test1.listener;

import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;

/**
 * Function:弹性效果
 * Created by xuzhuyun on 2016/8/16.
 */
public class ElasticTouchListener implements View.OnTouchListener {
    private View inner;
    View[] children;
    private float y;
    private Rect normal = new Rect();
    private boolean animationFinish = true;
    private int[] tops;
    private int[] bottoms;

    @Override
    public boolean onTouch(View v, MotionEvent ev) {
        if (inner == null && children == null) {
            if (v instanceof ViewGroup) {
                ViewGroup group = (ViewGroup) v;
                int count = group.getChildCount();
                if (count > 0) {
                    children = new View[count];
                    tops = new int[count];
                    bottoms = new int[count];
                    for (int i = 0; i < count; i++) {
                        children[i] = group.getChildAt(i);
                        tops[i] = children[i].getTop();
                        bottoms[i] = children[i].getBottom();
                    }
                }
            }
            inner = v;
        }
        if (animationFinish && (inner != null || children != null)) {
            int action = ev.getAction();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
//              System.out.println("ACTION_DOWN");
                    y = ev.getY();
                    break;
                case MotionEvent.ACTION_UP:
//              System.out.println("ACTION_UP");
                    y = 0;
                    if (isNeedAnimation()) {
                        animation();
                    }
                    inner.invalidate();
                    break;
                case MotionEvent.ACTION_MOVE:
//              System.out.println("ACTION_MOVE");
                    final float preY = y == 0 ? ev.getY() : y;
                    float nowY = ev.getY();
                    int deltaY = (int) (preY - nowY);
                    y = nowY;
                    // 当滚动到最上或者最下时就不会再滚动,这时移动布局
                    if (isNeedMove()) {
                        if (normal.isEmpty()) {
                            // 保存正常的布局位置
                            normal.set(inner.getLeft(), inner.getTop(), inner.getRight(), inner.getBottom());
                        }
                        if (children != null) {
                            View view = null;
                            for (int i = 0; i < children.length; i++) {
                                view = children[i];
                                view.layout(view.getLeft(), view.getTop() - deltaY / 2, view.getRight(), view.getBottom() - deltaY / 2);
                            }
                        } else {
                            // 移动布局
                            inner.layout(inner.getLeft(), inner.getTop() - deltaY / 2, inner.getRight(), inner.getBottom() - deltaY / 2);
                        }
                    }
                    inner.invalidate();
                    break;
                default:
                    break;
            }
        } else {
            return false;
        }
        return true;
    }

    // 开启动画移动

    public void animation() {
        if (children == null) {
            // 开启移动动画
            TranslateAnimation trans = new TranslateAnimation(0, 0, 0, normal.top - inner.getTop());
            trans.setDuration(200);
            trans.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                    animationFinish = false;
                }
                @Override
                public void onAnimationRepeat(Animation animation) {
                }
                @Override
                public void onAnimationEnd(Animation animation) {
                    inner.clearAnimation();
                    // 设置回到正常的布局位置
                    inner.layout(normal.left, normal.top, normal.right, normal.bottom);
                    normal.setEmpty();
                    animationFinish = true;
                }
            });
            inner.startAnimation(trans);
        } else {
            for (int i = 0; i < children.length; i++) {
                final View view = children[i];
                if (view.getVisibility() == View.VISIBLE) {
                    final int index = i;
                    // 开启移动动画
                    TranslateAnimation trans = new TranslateAnimation(0, 0, 0, tops[i] - view.getTop());
                    trans.setDuration(200);
                    trans.setAnimationListener(new Animation.AnimationListener() {
                        @Override
                        public void onAnimationStart(Animation animation) {
                            animationFinish = false;
                        }
                        @Override
                        public void onAnimationRepeat(Animation animation) {

                        }
                        @Override
                        public void onAnimationEnd(Animation animation) {
                            view.clearAnimation();
                            // 设置回到正常的布局位置
                            view.layout(view.getLeft(), tops[index], view.getRight(), bottoms[index]);
                            normal.setEmpty();
                            animationFinish = true;
                        }
                    });
                    view.startAnimation(trans);
                }
            }
        }

    }

    // 是否需要开启动画
    public boolean isNeedAnimation() {
        return !normal.isEmpty();
    }

    // 是否需要移动布局
    public boolean isNeedMove() {
//      int offset = inner.getMeasuredHeight() - getHeight();
//      int scrollY = getScrollY();
//      if (scrollY == 0 || scrollY == offset) {
//          return true;
//      }
//      return false;

//      if (children != null && children.length > 0
//              && (children[children.length - 1].getBottom() <= inner.getPaddingTop()/*inner.getTop()*/
//              || children[0].getTop() >= inner.getHeight()
//              )) {
//          return false;
//      }

        return true;
    }
}


2.编写测试Activity

package test.xzy.com.test1;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;

import test.xzy.com.test1.listener.ElasticTouchListener;

/**
 * Android自定义控件_让每一个Activity UI都具有弹性
 * 可以识别Touch手势,比如下拉,上拉的弹性效果
 * 具体步骤为:
 * 1.定义监听器ElasticTouchListener
 * 2.1全局UI弹性:在onCreate()方法中引用该监听,代码为:
 * View view = getLayoutInflater().inflate(R.layout.activity_main, null);
 * view.setOnTouchListener(new ElasticTouchListener());位置在super.onCreate()与setContetView()之间
 * 2.2设置view:setContentView(view);
 * 3.对于某个view,设置弹性效果,仅需在需要弹性的Root VIew 上加上监听。就能达到弹性的效果了,
 * 举例:ScrollView sv = (ScrollView)findViewById(R.id.sv_device_list);
 * sv.setOnTouchListener(new ElasticTouchListener());
 */
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        View view = getLayoutInflater().inflate(R.layout.activity_main, null);
        view.setOnTouchListener(new ElasticTouchListener());
        setContentView(view);
    }
}

大功告成,有时间介绍一下ScrollView,ListView等控件的弹性效果。

参考http://www.ithao123.cn/content-6831021.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值