仿华为手机系统抽屉效果,控件拖动

这是一个下拉抽屉,仿华为手机的系统下拉抽屉

未使用动画,是折叠打开效果,如使用压缩打开和移动打开效果,请加缩放动画和平移动画
本demo是动态改变高度,主要用到了ontouch方法
直接附上效果图和activity

/*
* 这是一个下拉抽屉,仿华为手机的系统下拉抽屉
* 未使用动画,是折叠打开效果,如使用压缩打开和移动打开效果,请加缩放动画和平移动画
* 本demo是动态改变高度
* */
public class MainActivity extends AppCompatActivity implements View.OnTouchListener, GestureDetector.OnGestureListener{
    //滚动布局
    ScrollView show;
    //滑动按钮
    Button btn;
    //动态改变布局用
    private RelativeLayout.LayoutParams linearParams;
    //配合ontouch使用,手势监听
    private GestureDetector mGestureDetector;
    int phone_high;//屏幕的高度
    int stop_high;//需要停留的位置
    int small_high = 100;//最小位置
    int speed = 50;//自动展开或收回的滑动速率,默认为50,大小自己设,越大越快

    //设定定时器用来自动弹回和弹出
    Handler myHanlder = new Handler();
    Runnable run=new Runnable() {
        @Override
        public void run() {
            //向上收回
            if(stop_high == small_high){
                if(linearParams.height>stop_high){
                    //速率自己调
                    linearParams.height = linearParams.height-speed;
                    show.setLayoutParams(linearParams); // 使设置好的布局参数应用到控件
                    // 递归
                    myHanlder.postDelayed(run, 1);
                }
             //向下展开
            }else if(stop_high == phone_high){
                if(linearParams.height<stop_high){
                    linearParams.height = linearParams.height+speed;
                    show.setLayoutParams(linearParams); // 使设置好的布局参数应用到控件
                    // 递归
                    myHanlder.postDelayed(run, 1);
                }
            }else {

            }

        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        show = (ScrollView) findViewById(R.id.show);
        btn = (Button) findViewById(R.id.btn);

        // 取控件当前的布局参数
        linearParams = (RelativeLayout.LayoutParams) show.getLayoutParams();
        btn.setOnTouchListener(this);
        mGestureDetector = new GestureDetector(this);
        mGestureDetector.setIsLongpressEnabled(true);

        //获取屏幕的高度
        phone_high = getMetrics().heightPixels;

    }




    @Override
    public boolean onTouch(View v, MotionEvent event) {
        //触摸返回值
        int action = event.getAction();
        switch (action) {
            //开始触摸
            case MotionEvent.ACTION_DOWN:
                //开始触摸时候返回的坐标
                //取消计时器
                myHanlder.removeCallbacks(run);
                break;
            //触摸移动
            case MotionEvent.ACTION_MOVE:
                //动态设定布局的高度为手势移动的高度
                if(event.getRawY()>=small_high){
                    linearParams.height = (int) event.getRawY();
                    show.setLayoutParams(linearParams);
                }
                break;
            //终止触摸
            case MotionEvent.ACTION_UP:
                break;
        }
//        return false;
        //引入手势,为了抓取到加速度,不引入的话,自己算比较麻烦
        return mGestureDetector.onTouchEvent(event);
    }

    //获取屏幕高度的方法
    private  DisplayMetrics getMetrics(){
        WindowManager wm = getWindowManager();
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        return outMetrics;
    }




    //以下为手势监听,配合ontouch方法使用
    //滑动的距离和速率。为了判断手势
    final int FLING_MIN_DISTANCE = 50, FLING_MIN_VELOCITY = 200;
    @Override
    public boolean onDown(MotionEvent e) {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        //判断当滑动距离大于50并且速率大于200,即自动收回,向上滑动
        if (e1.getRawY() - e2.getRawY() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
            //停止的高度为50,就是抽屉的最后的停留位置
            stop_high = small_high;
            myHanlder.post(run);
            /*之前用的动画但是不是想要的效果,如果
            想达到想要的效果还要动态改变上部外
            边距,索性直接用了定时器来取代动画*/
                /*if(animation!=null){
                    animation.cancel();
                }
                animation = new TranslateAnimation(0, 0, 0, -e2.getRawY());
                animation.setDuration(500);
                show.startAnimation(animation);*/
            //判断当滑动距离小于50并且速率大于200,即自动展开,向下滑动
        }else if(e1.getRawY() - e2.getRawY() <- FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
            //停止的高度即屏幕高度,就是抽屉的最后的停留位置
            stop_high = phone_high;
            myHanlder.post(run);

        }
        return false;
    }
}


附上demo的地址:http://download.csdn.net/detail/kac930/9797456

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值