卡片式切换效果

uni-app实现卡片切换效果 切换主题+css样式第一步:先看效果第二步:卡片的切换第三步:切换卡片内部的样式 第一步:先看效果 第二步:卡片的切换 <view class='bgDemo'> <view v-for="item,index in objectMultiArray" :key="index" @click='bindMultiPickerChange2' :data-id="index" style='z-index:50;'> <image :src="ite 阅读详情

今天跟大家分享一个卡片切换的效果:

70

一个说不上酷炫但很有意思的效果mad.gif

首先大体思路是:效果有多个View和动画组成的集合,既然是多个View那么复用肯定是首先要想到的,我这边用到的是RecycleView ,控件的叠加效果可以通过自定义RecycleView的LayoutManager来实现,而RecycleView并没有提供相关Api来支持拖拽效果的监听,好在SDK提供的一个强大的工具类ItemTouchHelper 来让我们实现RecycleView条目的拖拽效果。

现在让我们一步步实现:
先来一波常规操作:
70

这里就不贴代码了就是写了几个带圆角的shape作为背景,然后就是RecycleView一些普通的代码。

然后就是自定义LayoutManager,需要实现generateDefaultLayoutParams()方法,这个方法主要为设置LayoutManager的RecycleView提供LayoutParams参数

@Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
        return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
    }

 

实现叠加效果重点在于在onLayoutChildren()方法中对显示的item和位置重新排布

 

 

@Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        super.onLayoutChildren(recycler, state);

        //将所有的itemView先全部detach,放到Scrap集合里面,进行重新排布
        detachAndScrapAttachedViews(recycler);

        //获取当前recycler中的条目书
        int count = getItemCount();

        //取条目中前最大显示数的条目下标
        int mShowItemPos;
        if(count<=mMaxShowCount){
            mShowItemPos = 0;
        }else{
            mShowItemPos = count-mMaxShowCount;
        }

        //遍历排布
        for(int i = mShowItemPos;i<count;i++){
            //获取item 并添加到recycle中
            View item = recycler.getViewForPosition(i);
            addView(item);

            //测量item
            measureChildWithMargins(item,0,0);
            //确定摆放位置
            //获取除item之外的空余空间 + 偏移量 让整体卡片横向居中
            int left = (getWidth()-getDecoratedMeasuredWidth(item))/2+mOffsetRight;
            int top = (getHeight()-getDecoratedMeasuredHeight(item))/2;

            //重新摆放
            layoutDecorated(item,left,top,left+getDecoratedMeasuredWidth(item),top+getDecoratedMeasuredHeight(item));
        }
    }

设置给RecycleView之后发现只剩一个item,其他的item位置均一样所给给覆盖住

70

我们需要根据不同层级进行不同的位置和缩放即可实现叠加效果,代码如下:

 //当前item的层级 0 1 2 3
 int tier = count-i-1;
 //根据不同层级进行偏移和缩放
 item.setTranslationY(tier * mTransLB / 2); //向下偏移
 item.setTranslationX(-tier * mTransLB); //向左偏移
 //宽高缩放
 item.setScaleX(1-mScaleRate*tier);
 item.setScaleY(1-mScaleRate*tier);

70

层级效果已经完成然后就是左右切换的效果
切换效果需要我们自己定义ItemTouchHelper,并复写 onMove(),onSwiped()等方法
onMove()方法为移动条目时所需要处理的方法,这里直接返回默认false即可

onSwiped() 方法是滑动结束后所触发的方法
我们还需要复写两个重要的方法
getMovementFlags() 设置滑动的方向(也可以在构造器中设置方向)
onChildDraw() 设置item移动时的动画效果
直接贴上代码

public class SwipeCardCallBack extends ItemTouchHelper.SimpleCallback {
    private RecyclerView mRecyclerView;
    private List<Integer> mDatas;
    //当前item最大显示数
    private int mMaxShowCount = 4;

    //item左下偏移
    private int mTransLB;

    //item缩放比例
    private float mScaleRate = 0.05f;

    public SwipeCardCallBack(Context context) {
        super(0, 0);
        mTransLB = DensityUtils.dp2px(context,15);
    }

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        int swipeFlags = 0;
        mRecyclerView = recyclerView;
        RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();

        if (layoutManager instanceof SwipeCardLayoutManager) {
            //设置滑动的方向
            swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT ;

        }

        return makeMovementFlags(0, swipeFlags);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return false;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        //移除并添加数据实现循环
        SwipeCardAdapter swipeCardAdapter = (SwipeCardAdapter) mRecyclerView.getAdapter();
        mDatas = swipeCardAdapter.getDatas();
        int bg = mDatas.remove(viewHolder.getLayoutPosition());
        mDatas.add(0,bg);
        swipeCardAdapter.notifyDataSetChanged();
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        //最大移动距离
        double maxMove = Math.hypot(recyclerView.getWidth()/2,recyclerView.getHeight()/2);
        //当前移动距离
        double currentMove = Math.hypot(dX,dY);

        //当前动画的进度
        double p = currentMove/maxMove>1?1:currentMove/maxMove;
        int count = recyclerView.getChildCount();
        for (int i = 0; i < count; i++) {
            //执行
            View item = recyclerView.getChildAt(i);
            int tier = count - i - 1;
            if (tier > 0) {
                if (tier < mMaxShowCount) {
                    //将其他层级的item进行向中偏移并放大
                    item.setTranslationX((float) (1 - mTransLB * tier + p * mTransLB));
                    item.setTranslationY((float) -(1 - mTransLB * tier + p * mTransLB)/2);
                    item.setScaleX((float) (1 - mScaleRate * tier + p * mScaleRate));
                    item.setScaleY((float) (1 - mScaleRate * tier + p * mScaleRate));
                }
            }else{
                if(dX!=0){
                    //根据item的移动方向的不同进行不同的角度反转
                    item.setRotation((float) (p * 45*dX/Math.abs(dX)));
                }
            }
        }

    }


    //防止除了最顶上的item滑动外,其他层级的item也滑动,需要在LayoutManager中重新设置顶层item的滑动监听
    @Override
    public boolean isItemViewSwipeEnabled() {
        return false;
    }

    //旋转后由于条目复用会使下一层的item也进行旋转
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        //重置角度
        viewHolder.itemView.setRotation(0f);
    }
}

还需要重置最上层的滑动监听,直接贴出SwipeCardLayoutManager代码

public class SwipeCardLayoutManager extends RecyclerView.LayoutManager {
    //当前item最大显示数
    private int mMaxShowCount = 4;
    //向左右展示偏移
    private int mOffsetRight = 20;
    //item左下偏移
    private int mTransLB;
    //item缩放比例
    private float mScaleRate = 0.05f;

    private Context mContext;

    private RecyclerView mRecyclerView;

    private ItemTouchHelper mHelper;
    public SwipeCardLayoutManager(Context context, RecyclerView recyclerView, ItemTouchHelper helper) {
        mContext = context;
        mTransLB = DensityUtils.dp2px(context,15);
//        mOffsetRight = mTransLB*mMaxShowCount;
        mRecyclerView = recyclerView;

        mHelper = helper;
    }

    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
        return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        super.onLayoutChildren(recycler, state);

        //将所有的itemView先全部detach,放到Scrap集合里面,进行重新排布
        detachAndScrapAttachedViews(recycler);

        //获取当前recycler中的条目书
        int count = getItemCount();

        //取条目中前最大显示数的条目下标
        int mShowItemPos;
        if(count<=mMaxShowCount){
            mShowItemPos = 0;
        }else{
            mShowItemPos = count-mMaxShowCount;
        }

        //遍历排布
        for(int i = mShowItemPos;i<count;i++){
            //获取item 并添加到recycle中
            View item = recycler.getViewForPosition(i);
            addView(item);

            //测量item
            measureChildWithMargins(item,0,0);
            //确定摆放位置
            //获取除item之外的空余空间 + 偏移量 让整体卡片横向居中
            int left = (getWidth()-getDecoratedMeasuredWidth(item))/2+mOffsetRight;
            int top = (getHeight()-getDecoratedMeasuredHeight(item))/2;

            //重新摆放
            layoutDecorated(item,left,top,left+getDecoratedMeasuredWidth(item),top+getDecoratedMeasuredHeight(item));

            //当前item的层级 0 1 2 3
            int tier = count-i-1;
            //根据不同层级进行偏移和缩放
            item.setTranslationY(tier * mTransLB / 2); //向下偏移
            item.setTranslationX(-tier * mTransLB); //向左偏移
            //宽高缩放
            item.setScaleX(1-mScaleRate*tier);
            item.setScaleY(1-mScaleRate*tier);

            //当为最上层的item时获取拖动事件
            if(tier==0){
                item.setOnTouchListener(mOnTouchListener);
            }
        }
    }

    private View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            RecyclerView.ViewHolder childViewHolder = mRecyclerView.getChildViewHolder(v);
            // 把触摸事件交给 mItemTouchHelper,让其处理卡片滑动事件
            if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
                mHelper.startSwipe(childViewHolder);
            }
            return false;
        }
    };
}

以上就完成了所有效果。

完整项目地址

 

微信小程序 - 实现容器卡片翻转动画效果,类似考勤打卡签到时翻转效果(像翻牌抽奖类似的效果动画)详细示例源码教程,一键复制开箱即用! 微信小程序容器翻转效果css,微信小程序实现点击卡片翻转效果详细教程,微信小程序卡片翻转动画示例源码,微信小程序类似钉钉打卡翻转动画,微信小程序实现图片翻转效果的实例代码,微信小程序实现打卡签到页面,微信小程序打卡动画怎么做。微信小程序实现翻牌抽奖动画,微信小程序如何实现卡片内容翻转切换动画,微信小程序翻转动画,微信小程序 Animation实现图片翻转旋转动画示例,微信小程序仿钉钉打卡签到动画功能,微信小程序点击翻转到背面效果,微信小程序实现翻效果,微信小程序:图片翻转特效,微信小程序实现打卡(翻转效果) 阅读详情

相关推荐

HTML5+CSS3+JS小实例:小清新的卡片式注册登录切换效果

实例:小清新的卡片式注册登录切换效果。技术栈:HTML+CSS+JS。

艾恩小灰灰的博客 349

Android可拖动层叠卡片布局

公司app要求做一个扭蛋功能,其实就是一个可拖动层叠卡片列表,原理还是由一个自定义Recyclerview和LayoutManager来实现 自定义RecyclerView很简单,只是修改touch事件,防止点击到卡片外还被处理的情况 @Override public boolean onTouchEvent(MotionEvent e) { if(e.getY()< UIUtil.dip2px(TutuApplication.getInstance().getCont

a__sen的博客 998

HTML5+CSS3+JS小实例:小清新的卡片式注册登录切换效果①

小清新的卡片式注册登录切换效果

前端必备小窝 872

css实现卡片内容动态切换效果

css实现卡片内容动态切换效果

weixin_43811753的博客 1640

CardLayoutManager:自定义layoutManager提供类似Tinder的纸牌效果

CardLayoutManager 简单、可扩展的一个LayoutManager,实现了类似于探探和Tinder,滑动图片 监听滑动中的事件与动画过程 支持smoothScrollToPosition和scrollToPosition 自定义LinearLayout.HORIZONTAL或者LinearLayout.VERTICAL 自定义显示卡片个数以及卡片之间的间隙 自定义显示卡片的排列方向: LEFT RIGHT TOP BOTTOM 自定义滑动方向: setVerticalSwipe setHorizontalSwipe 对滑动过程进行控制 简单易用,扩展性高 预览 滑动 和 smoothScrollToPosition 初始化 CardLayoutManager layoutManager = new CardLayoutManager(); recyclerView.setLa

RAGFlow 离线部署:解决cl100k_base.tiktoken问题

摘要 本文详细解决了RAGFlow离线部署时tiktoken缓存文件下载失败的问题。通过分析tiktoken库的缓存机制,一次性不改代码解决.

baidu_25691461的博客 832

ios卡片式切换效果_Material Design和iOS色彩模式比较

Material Design的色彩Material Design带有一个基准色彩主题,包括浅色模式和深色模式。用户可以直接使用基准主题色彩,也可以自定义基准色彩,然后应用到UI。同时,深色主题中,应用不同的高度叠加层可以表示不同高度的表面iOS的色彩动态系统色彩iOS中,苹果官方推荐使用动态系统色彩。动态系统色彩可以按照深色或浅色模式、对比度、不透明度等用户设置自动进行调整。这些色彩是按照语义化...

weixin_35003319的博客 574

从平衡车到寻迹小车:IMU963RA九轴陀螺仪实战避坑与四元数融合指南

本文详细解析了IMU963RA九轴陀螺仪在机器人姿态控制中的应用,重点探讨了从六轴升级到九轴系统的技术路径及四元数融合算法。通过实战案例,揭示了如何利用地磁计补偿陀螺积分漂移,并提供硬件集成、传感器校准及算法实现的完整解决方案,有效将8小时漂移控制在2度以内。

weixin_27219587的博客 255

ios 卡片层叠切换效果_开源ReactNative卡片式(Cards)组件,你值得拥有

开源一个跨端的卡片式设计(Cards)的组件,在Android中是Material Design中有一种很个性的设计概念,在使用React-Native跨平台的开发框架中,卡片样式在IOS平台通过设置View的样式就可以实现类似的效果,比如这样:<View style={{ shadowOffset: { // 设置阴影偏移量 width: 0, ...

weixin_39970994的博客 1061

1976国际标准大气_Matlab

输入高度,计算空气密度、气压、温度、声速 function [airDens,airPress,temp,soundSpeed]=Atmos(geomAlt) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 1976 U.S Standard Atmosphere Interpolation % % Note: Function does not extr.

JISANSAN的博客 1万+

基于python CNN卷积神经网络模型实现6类别垃圾分类 毕业设计 附完整代码数据

基于python CNN卷积神经网络模型实现6类别垃圾分类 毕业设计 附完整代码数据

1665

vue卡片式点击切换图片组件

vue卡片式点击切换图片组件 因为公司业务的问题,最近在写vue项目,有了一个卡片图片的点击的需求,自己又不想写动画效果,就偷个懒,采用vue是以数据驱动的原理,写了一个不太完整的vue组件,为了简单,就直接上代码吧 全部代码 未进行props传参设置,以后完善(简单最好嘛) <template> <!-- *以数据驱动的card式展示图片(无动画效果) * --&gt...

前端结城的博客 5545

Istio ICA考试之路---2-2

找到dr部分,这部分可以在mirroring里找也可以和题2-1一样在Traffic Management的dr里复制,内容都一样。此题之后都是在cluster-2上操作,所以就不需要再切换了.之后的几题2.1节就忽略掉了。可以看到,80%的流量被镜像到了dev上,实际考试这步可以忽略。看到ex-ip是192.168.126.220。获取gw,把gateways加入到vs配置中。获取istio-ingress的ex-ip。就获得了这样一个模板文件。查看2个pod的日志。

Q先生 854

JS_卡片切换效果

最终效果图如所示: (个人方法,不是最简单的方法) 头部ul,用于显示的div的id设为details,容器div的id设为container。 布局:将ul和details放在容器container里面,ul和details均不设置float。通过设置container的width,来控...

chengqinzhi5893的博客 1276

在zcu102开发板上使用PetaLinux运行Qt程序

请注意,上述步骤只是一个概述,并且可能需要根据特定的开发环境和要求进行适当的调整。如果你是一个初学者或者对于这些领域不太熟悉,建议在尝试之前阅读相关的文档和教程,或者寻求专业人士的帮助。在"Projects"菜单中,选择"Build & Run"选项,并在"Build"步骤中选择正确的工具链。注意:如果Qt程序依赖于其他库文件,需要将这些库文件一起复制到PetaLinux工程的根文件系统目录中,并在Qt程序中正确地配置库文件路径。如果一切顺利,PetaLinux系统将启动,并自动运行Qt程序。

UhxzCombined的博客 698

AI工具赋能日常工作的实践指南:以产品经理与程序员为例

AI工具赋能日常工作的实践指南:以产品经理与程序员为例

专注于编程、AI、人工智能等多个领域内容研究和分析 592

ios卡片式切换效果_越来越像ios的安卓 以及我对全面屏手势的看法

全面屏手势将原本“用户按下按键——按键控制手机”的操作逻辑简化为“用户直接操控手机”。——UPTONIA9月4日,谷歌、小米、essential等品牌的部分手机陆续接到了安卓10的正式推送,而作为谷歌的亲儿子的一加,在新系统的测试上同样毫不落后。在经历了接近4个月、多达6个版本的开发者预览后,一加手机的安卓10测试即将迎来尾声。在现最新的beta6版本中,1+7pro获得了全新的“一加全屏手势”—...

weixin_39613540的博客 602

本地Pycharm连接远程服务器详细配置过程(直接在本地使用服务器显卡,很棒)

相信很多人都遇见过这种情况:实验室成员使用同一台服务器,每个人拥有自己的独立账号,我们可以使用服务器更好的配置完成实验,毕竟自己哪有money拥有自己的3090呢。

NorthSmile的博客 4万+

JS特效第139弹:卡片式的登录注册表单ui布局

经典的JS特效动画效果,效果实现的全部代码已提供,可供学习借鉴

weixin_38343072的博客 354

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

标签卡片式翻动浏览

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/1999/xhtml">标签卡片式翻动浏览html,body{ width:100%; height:100%; margin:0;}BODY { font-family:"雅黑","宋体",arial; FONT-SIZE: 12px; backg

jujuchen的专栏 652

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

android多个图片滑动切换效果,Android中实现类似探探中图片左右滑动切换效果

原标题:Android中实现类似探探中图片左右滑动切换效果偶然之间发现探探的左右滑动的图片挺好玩,试着去做了下,再到后来,看到许多大神也推出了同样仿探探效果的博客,从头到尾阅读下来,写得通俗易懂,基本上没什么问题。于是,实现仿探探效果的想法再次出现在脑海中。那么,还犹豫什么,趁热来一发吧!就这么愉快地决定了。RecyclerView 是最佳选择!RecyclerView 是最佳选择!Recycle...

weixin_32506743的博客 1708

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Java学习笔记之卡片式布局CardLayout

CardLayout(构造)方法: 方法 说明 public CardLayout() 创建一个间距大小为0的新卡片布局 public CardLayout(int hgap,int vgap) 创建一个具有指定水平间距和垂直间距的新卡片布局。水平间距置于左右边缘。垂直间距置于上下边缘 public void first(Container p

想去海邊 1万+

流畅的卡片滑动切换交互效果

一款流畅的卡片滑动切换交互效果,当滑动鼠标滚轮,卡片上下滚动切换的动画效果,十分流畅,用户体验感很好,适用于任何类型的网页中。

ICode联盟 438

Ext Js 3.2 卡片式布局--CardLayout应用

1:Ext.layout.CardLayout的介绍      CardLayout可以看作是一叠卡片,从上面看起来就像是一张卡片,可以把中间的卡片抽出来,放到最上面,可每次只能看到一张卡片,它能够 满足安装向导、Tab选项卡等应用面板显示的需求。   代码:   <% String path = request.getContextPath(); String basePath

张波的技术积累 4108
下一篇: 【转载】解决 IllegalStateException: Can not perform this action after onSaveInstanceState
Code_dh
博客等级 码龄8年 58粉丝 4原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值