Android 仿美团悬浮购物车显示隐藏

简介: Android 仿美团悬浮购物车显示隐藏

效果图:

image.png


这是美团的效果

image.png

通过效果图可以看到 静止的时候是购物车图标是显示的,滑动的时候是隐藏一半并半透明显示的。

这里用到一个触摸反馈的方法dispatchTouchEvent


MotionEvent.ACTION_DOWN://手指按下

MotionEvent.ACTION_MOVE://手指滑动

MotionEvent.ACTION_UP://手指抬起

整体的思路就是在滑动过程中,购物车图标向右位移,并加一个渐变效果。


image.png


向右移动的距离计算:屏幕的宽度减去图标距左边的宽度(红线),然后加上图标的半径(蓝线)


布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <ImageView
        android:id="@+id/iv_cart"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="60dp"
        android:layout_marginEnd="20dp"
        android:layout_marginRight="20dp"
        android:contentDescription="@null"
        android:src="@drawable/ic_cart"/>
</RelativeLayout>


代码

初始化控件

       mListView = findViewById(R.id.list_view);

       mIvCart = findViewById(R.id.iv_cart);


初始化数据

       for (int i = 0; i < 50; i++) {

           titles.add("第  -  " + i + "  -  条数据");

       }

       mListView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, titles));


计算移动距离

   

//控件绘制完成之后再获取其宽高
        mIvCart.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                //动画移动的距离 屏幕的宽度减去图片距左边的宽度 就是图片距右边的宽度,再加上隐藏的一半
                moveDistance = getScreenWidth() - mIvCart.getRight() + mIvCart.getWidth() / 2;
                //监听结束之后移除监听事件
                mIvCart.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });


 

private int getScreenWidth() {
        DisplayMetrics dm = new DisplayMetrics();
        this.getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm.widthPixels;
    }


隐藏动画

 

private void hideFloatImage(int distance) {
        isShowFloatImage = false;
        //位移动画
        TranslateAnimation ta = new TranslateAnimation(0, distance, 0, 0);
        ta.setDuration(300);
        //渐变动画
        AlphaAnimation al = new AlphaAnimation(1f, 0.5f);
        al.setDuration(300);
        AnimationSet set = new AnimationSet(true);
        //动画完成后不回到原位
        set.setFillAfter(true);
        set.addAnimation(ta);
        set.addAnimation(al);
        mIvCart.startAnimation(set);
    }


显示动画

 

private void showFloatImage(int distance) {
        isShowFloatImage = true;
        //位移动画
        TranslateAnimation ta = new TranslateAnimation(distance, 0, 0, 0);
        ta.setDuration(300);
        //渐变动画
        AlphaAnimation al = new AlphaAnimation(0.5f, 1f);
        al.setDuration(300);
        AnimationSet set = new AnimationSet(true);
        //动画完成后不回到原位
        set.setFillAfter(true);
        set.addAnimation(ta);
        set.addAnimation(al);
        mIvCart.startAnimation(set);
    }


处理滑动逻辑

 

@Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN://手指按下
                if (System.currentTimeMillis() - upTime < 1000) {
                    //本次按下距离上次的抬起小于1s时,取消Timer
                    timer.cancel();
                }
                startY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE://手指滑动
                if (Math.abs(startY - event.getY()) > 10) {
                    if (isShowFloatImage) {
                        hideFloatImage(moveDistance);
                    }
                }
                startY = event.getY();
                break;
            case MotionEvent.ACTION_UP://手指抬起
                if (!isShowFloatImage) {
                    //抬起手指1s后再显示悬浮按钮
                    //开始1s倒计时
                    upTime = System.currentTimeMillis();
                    timer = new Timer();
                    timer.schedule(new FloatTask(), 1000);
                }
                break;
        }
        return super.dispatchTouchEvent(event);
    }


这里用一个upTime 记录手指抬起的时间,如果小于1s动画就不执行,避免快速反复滑动导致动画多次执行。

然后用一个定时器timer延时执行动画

在手指抬起的时候记录当前时间戳,并执行动画

moveDistance就是计算的移动的距离

isShowFloatImage是一个布尔类型的标识,判断图标状态是否显示

startY - event.getY()) > 10 这个大于10是因为手指按下的是一个面,不是一个点,把这个面的高度定为10


github : https://github.com/yechaoa/FloatCartDemo



ok,完成,借鉴https://blog.csdn.net/Lindroid20/article/details/78887347

目录
相关文章
|
存储 数据库 Android开发
Android -- 购物车
Android -- 购物车
135 0
|
API Android开发
Android | 通过WindowInsetsController设置系统栏颜色、Behavior、显示隐藏等
两种方式可以引入`WindowInsetsController`,一种直接通过`API`的`val controller = window.decorView.windowInsetsController`获取,注意该方法在`API30`及以上才有
1068 0
|
JSON Android开发 数据格式
Android 购物车实现(思路+步骤+源码)
Android 购物车实现(思路+步骤+源码)
938 0
Android 购物车实现(思路+步骤+源码)
|
前端开发 JavaScript Java
Android 眼睛 显示隐藏密码(ImageView)
Android 眼睛 显示隐藏密码(ImageView)
209 0
Android 眼睛 显示隐藏密码(ImageView)
|
Java Maven Android开发
手撸了个很容易实现京东购物车吸顶功能的Android库
手撸了个很容易实现京东购物车吸顶功能的Android库
手撸了个很容易实现京东购物车吸顶功能的Android库
|
XML Android开发 数据格式
Android标题栏随着滑动显示隐藏
这次实现标题栏随着上滑下滑显示隐藏 实现这个效果需要,Support Design库中的CoordinatorLayout和AppBarLayout进行配合才行。
3317 0
|
安全 Android开发 开发者
Android-V1、V2签名包和快速集成美团多渠道打包(原创)
本文已独家授权 郭霖 ( guolin_blog) 公众号发布! 今天的文章主要介绍的是Android V1、V2签名包的基本概念和使用场景以及如何十分钟快速掌握美团多渠道打包。
1799 0
|
Android开发 容器 数据格式
Android 购物车功能的实现
首先,众所周知,ListView是Android最常用的控件,可以说是最简单的控件,也可以说是最复杂的控件。 作为一个Android初级开发者,可能会简单的ListView展示图文信息。 作为一个有一定项目开发经验的Android开发者来说,可能会遇到ListView的列表项中存在各种按钮的需求。
1167 0