如何用RecyclerView实现猫眼电影选择效果

RecyclerView实现Item居中效果(仿猫眼美团电影选择效果) 一、实现的效果 1、滑动的时候让每一个Item保持在中间 2、点击某一个Item让其滚动到中间 3、实际实现的效果如下:点击一次自动滚动居中,再次点击跳转到详情页   二、实现的思路: 1、每一次的滑动都让图片保持在中间,其实RecyclerView24.2.0版本以后,Google已经提供一个SnapHelper的辅助类,可以实现每一次滚动结束保持居中。具体用法就是: Li... 阅读详情

一、简介

在官方推出RecyclerView 控件之后,越来越多的人都使用它代替之前的ListView。除了最普通的列表显示,RecyclerView还可以其他的很多效果,例如Banner等。在最近的一个电影票平台项目中,使用RecyclerView实现了仿猫眼的电影选择控件,如下图所示:在这里插入图片描述
以上图为例,我们的需求如下:

1、每一次滑动都让图片保持在中间。
2、第一张图片的左边距和最后一张的右边距需要大于其他图片的边距使其保持在中间
3、点击某张图片时让其滑动到中间
4、背景实现高斯模糊
5、在切换当前电影时有一个背景淡入淡出的效果

二、实现思路

我们一步步实现我们的需求

(1)每一次滑动都让图片保持在正中间

滑动保持图片在正中间,在RecyclerView24.2.0之后,Google官方给我们提供了一个SnapHelper的辅助类,可以帮助我们实现每次滑动结束都保持在居中位置:

val movieSnapHelper = LinearSnapHelper()
movieSnapHelper.attachToRecyclerView(movieRecyclerView)

LinearSnapHelper类是SnapHelper的一个子类,SnapHelper的另一个子类叫做PagerSnapHelper。顾名思义,两者都可以是滑动结束时item保持在正中间,但是LinearSnapHelper可以一次滑动多个item,而PagerSnapHelper像ViewPager一样限制你一次只能滑动一个item。

(2)第一张图片的左边距和最后一张的右边距需要大于其他图片的边距使其保持在中间

由于第0个item和最后一个item的图片边距比较特殊,而其他的都是默认边距,如果不做设置,第一张和最后一张图片就无法位于正中间,如下图所示:在这里插入图片描述
在这里插入图片描述
如果想要是第0位置的图片保持在中间,我们需要动态设置第0位置的图片的左边距为 (屏幕宽度-自定义ImageView图片宽度-自定义ImageView的Margin)/2,例如我自定义的view参数为下图在这里插入图片描述
图片宽度+图片margin为110dp,假设手机屏幕宽度为360dp,我们此时图片的左边距便设置为(360-110)/2 = 125 dp。

动态修改item的LayoutParams,我们不要在自定义的Adapter里直接更改,官方提供了ItemDecoration的api,可以给recyclerview的item添加装饰,我们在这里自定义一个继承RecyclerView.ItemDecoration的GalleryItemDecoration,然后重写getItemOffsets(outRect: Rect?, view: View?, parent: RecyclerView?, state: RecyclerView.State?)方法(此方法用于自定义item的偏移宽度),修改如下:

class GalleryItemDecoration : RecyclerView.ItemDecoration() {

    var mPageMargin = 10 //自定义默认item边距
    var mLeftPageVisibleWidth = 125 //第一张图片的左边距

    override fun getItemOffsets(outRect: Rect?, view: View?, parent: RecyclerView?, state: RecyclerView.State?) {
        val positon = parent?.getChildAdapterPosition(view) //获得当前item的position
        val itemCount = parent?.adapter?.itemCount //获得item的数量
        val leftMargin = if (positon == 0) dpToPx(mLeftPageVisibleWidth) else dpToPx(mPageMargin) //如果position为0,设置leftMargin为计算后边距,其他为默认边距
        val rightMargin = if (positon == (itemCount!! - 1)) dpToPx(mLeftPageVisibleWidth) else dpToPx(mPageMargin) //同上,设置最后一张图片
        val lp = view?.layoutParams as RecyclerView.LayoutParams
        lp.setMargins(leftMargin, 30, rightMargin, 60) //30和60分别是item到上下的margin
        view.layoutParams = lp //设置参数
        super.getItemOffsets(outRect, view, parent, state)
    }

    private fun dpToPx(dp: Int): Int { 
        return (dp * Resources.getSystem().displayMetrics.density + 0.5f).toInt() //dp转px
    }
}

然后,recyclerview设置GalleryItemDecoration即可:

movieRecyclerview.addItemDecoration(GalleryItemDecoration())

(3)点击某张图片时让其滑动到中间

在RecyclerView中,我们如果需要滑动到某一位置,一般会使用RecyclerView.smoothScrollToPosition(idx)方法,但是在此处我们在设置item的点击事件时,不能直接使用这个方法,因为这个方法只会将recyclerview滑动到idx位置的item可见便停止了,而无法移动到中间。

我们通过查询,在stackoverflow上找到了实现思路,自定义一个LinearLayoutManager,代码如下:

class CenterLayoutManager:LinearLayoutManager{
    constructor(context:Context):super(context)
    constructor(context:Context,orientation:Int,reverseLayout:Boolean):super(context,orientation,reverseLayout)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int):super(context, attrs, defStyleAttr, defStyleRes)

    override fun smoothScrollToPosition(recyclerView: RecyclerView?, state: RecyclerView.State?, position: Int) {
        val smoothScroller = CenterSmoothScroller(recyclerView!!.context)
        smoothScroller.targetPosition = position
        startSmoothScroll(smoothScroller)
    }

    private class CenterSmoothScroller internal constructor(context: Context) : LinearSmoothScroller(context) {
        override fun calculateDtToFit(viewStart: Int, viewEnd: Int, boxStart: Int, boxEnd: Int, snapPreference: Int): Int {
            return boxStart + (boxEnd - boxStart) / 2 - (viewStart + (viewEnd - viewStart) / 2)
        }

    }
}

我们通过查看源码,RecyclerView.smoothScrollToPosition(idx)调用了LinearLayoutManager.smoothScrollToPosition方法,代码中的calculateDtToFit 方法控制滑动的位置,其中参数中view为需要滑动可见的item,box为整个布局。 然后调用val movieLayoutManager = CenterLayoutManager(this)和 RecyclerView.smoothScrollToPosition(idx)便可以点击滑动到中间。

(4)背景实现高斯模糊

高斯模糊有很多方法,推荐使用Native层的实现,使用RenderScript,此处参考教程教你一分钟实现动态模糊效果,自定义一个ImageUtil类进行处理:

class ImageUtils(val context: Context) {

    private var renderScript:RenderScript? = RenderScript.create(context)

    fun gaussianBlur(@IntRange(from = 1,to = 25)radius:Int,original:Bitmap):Bitmap{
        val input = Allocation.createFromBitmap(renderScript,original)
        val output = Allocation.createTyped(renderScript,input.type)
        val scriptInterinsicBlur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript))
        scriptInterinsicBlur.setRadius(radius.toFloat())
        scriptInterinsicBlur.setInput(input)
        scriptInterinsicBlur.forEach(output)
        output.copyTo(original)
        return original
    }
}

用法只需要new一个ImageUtils对象,传入context,然后在方法里传入模糊程度(1到25)和原始bitmap即可,然后将这个bitmap设置为RecyclerView的背景即可。

(5)在切换当前电影时有一个背景淡入淡出的效果

private fun setMovieRecBg(idx: Int) {
        doAsync {
            val imageManager = ImageUtils(this@CinemaDetailActivity)
            val bgBitmap = Glide.with(applicationContext).asBitmap().load(mMovieList[idx].coverSrc).submit(300, 520).get()
            uiThread {
                if (!isActivityDestroyed(this@CinemaDetailActivity)) {
                    val curBg = BitmapDrawable(resources, imageManager.gaussianBlur(25, bgBitmap))
                    val preBg = if (bgCacheMap["PRE_BG"] == null) curBg else bgCacheMap["PRE_BG"]
                    val options = RequestOptions().placeholder(preBg).diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)
                    Glide.with(this@CinemaDetailActivity).load(bgBitmap).apply(options).transition(DrawableTransitionOptions.withCrossFade(1000)).into(cinema_detail_moviebg)
                    bgCacheMap["PRE_BG"] = curBg
                }
            }
        }
    }

本例中使用Glide框架加载图片,因为加载的是网络url,在使用高斯模糊的时候我们需要使用方法将url转为bitmap,因为是网络,我们不能再主线程里完成,因此需要新开一个线程,在Glide中,可以设定一个占位符,即网络图片加载之前的默认图片,然后在加载图片时可以使用transition进行淡入淡出,这里我们新建一个Map来缓存上一张图片的背景图片,然后当做下一张图片的占位符,便可以实现背景淡入淡出效果。
最后小编给大家整理的一些高级安卓程序员必备的学习资料
加QQ群即可获取:4112676

仿IOS百度糯米电影横向滑动效果 仿IOS百度糯米电影横向滑动效果,滑动到中间位置进行电影海报放大 立即下载

相关推荐

Android_RecycleView_Lista:实施电影列表应用程序RecycleView

Android_RecycleView_Lista:实施电影列表应用程序RecycleView

手把手教你用RecyclerView实现猫眼电影选择效果

一、简介 在官方推出RecyclerView 控件之后,越来越多的人都使用它代替之前的ListView。除了最普通的列表显示,RecyclerView还可以其他的很多效果,例如Banner等。在最近的一个电影票平台项目中,使用RecyclerView实现了仿猫眼的电影选择控件,如...

weixin_33754065的博客 533

一个用RecyclerView实现的画廊效果,被选中item居中放大,效果很自然。

一个用RecyclerView实现的画廊效果,被选中item居中放大,效果很自然。

实现类似猫眼影片详情页电影海报滚动效果(RcyclerView+LinearSnapHelper )

Github (前一篇ViewPager实现和本篇的代码,都在这个项目) 效果 第一行为ViewPager实现效果 第二行为RcyclerView+LinearSnapHelper 实现效果 重点LinearSnapHelper是什么 LinearSnapHelper是一个让 RcyclerView在滑动scroll、快速滑动fling过程中,使得最后停止在一个Item的中间

Android_Study_OK的博客 3603

iOS面试题大全(附带答案)

C语言相关面试题 1.static有什么用途? 答案:在C语言中,static主要定义全局静态变量,定义局部静态变量,定义静态函数。 static 属于静态变量,使用它修饰的变量生命周期是整个源程序。 @1.在函数体内的 static 变量的作用范围为该函数体,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值; @2.在模块内的 static 全局变量可以被模块内所有函数访问,但不能被模块外其它函数访问; @3.在模块内的 static 函数只被这一模块内的其它函数调用,这个函数的使用范围被限

IOSNF的博客 2425

STM32F103到F407移植OLED,为啥F4屏幕不亮?一个延时函数搞定时序问题

本文详细分析了STM32F103到F407移植OLED时屏幕不亮的问题,指出时钟频率差异导致的时序问题是关键原因。通过对比F103和F407的时钟架构差异,提供了精确延时函数的实现方法,并指导在I2C通信关键点插入适当延时,确保OLED正常显示。文章还涵盖了完整的测试方案和高级优化技巧,帮助开发者彻底解决移植中的时序问题。

weixin_30642561的博客 549

Android使用RecyclerView实现投票系统

一、创建一个fragment_vote_list.xml用来显示投票的主页面 (1)标题栏使用Toolbar (2)投票区域可以滑动,使用RecyclerView实现 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/an...

柯小帅的博客 1987

别再踩坑了!手把手教你用EB Tresos Studio创建Autosar MCAL工程(含模块配置避坑指南)

本文详细介绍了使用EB Tresos Studio创建Autosar MCAL工程的完整流程,包括工程创建前的关键准备、模块配置的避坑指南以及工程验证与代码生成的实用技巧。通过实战案例和黄金准则,帮助开发者高效完成MCAL工程创建,避免常见错误,提升开发效率。

weixin_42536058的博客 444

recyclerview居中显示_如何用RecyclerView实现猫眼电影选择效果

一、简介在官方推出RecyclerView 控件之后,越来越多的人都使用它代替之前的ListView。除了最普通的列表显示,RecyclerView还可以其他的很多效果,例如Banner等。在最近的一个电影票平台项目中,使用RecyclerView实现了仿猫眼的电影选择控件,如下图所示:以上图为例,我们的需求如下:1、每一次滑动都让图片保持在中间。2、第一张图片的左边距和最后一张的右边距需要大于其...

weixin_39533307的博客 571

图像处理(12)--图像各种噪声及消除方法

文章目录结构1.什么是图像噪声2. 图像噪声来源3. 噪声分类及其消除方法3.1 高斯噪声及其消除方式3.1.1 如何确定一种噪声是高斯噪声3.1.2 高斯滤波消除高斯噪声3.1.3 高斯函数的重要性质3.2 瑞利噪声及其消除方式3.3 伽马(爱尔兰)噪声及其消除方式3.4 指数分布噪声及其消除方式3.5 均匀噪声及其消除方式3.6 脉冲(椒盐)噪声及其消除方式 1.什么是图像噪声 图像噪声是指...

ShaneHolmes 11万+

给新人的储能系统入门图解:从电芯到EMS,一张图看懂BESS里那些‘黑话’

本文通过视觉化拆解储能系统,从电芯到EMS详细解析BESS中的关键组件和行业术语。涵盖电芯参数、模组组装、PCS功能、BMS与EMS分工,以及SOC、DOD等关键运维参数,帮助新人快速理解储能系统的核心技术和应用场景。

weixin_42522964的博客 592

recyclerview item 点击有背景_如何用RecyclerView实现猫眼电影选择效果

一、简介在官方推出RecyclerView 控件之后,越来越多的人都使用它代替之前的ListView。除了最普通的列表显示,RecyclerView还可以其他的很多效果,例如Banner等。在最近的一个电影票平台项目中,使用RecyclerView实现了仿猫眼的电影选择控件,如下图所示:以上图为例,我们的需求如下:1、每一次滑动都让图片保持在中间。2、第一张图片的左边距和最后一张的右边距需要大于其...

weixin_39958366的博客 459

Ubuntu升级遇到grub-efi-amd64-signed报错?3步搞定这个烦人的EFI目录问题

本文详细解析了Ubuntu系统升级时遇到的“grub-efi-amd64-signed”报错及“cannot find EFI directory”问题。通过剖析UEFI启动机制与EFI系统分区原理,提供了从诊断到修复的三步解决方案,帮助用户快速解决因EFI目录未挂载导致的升级中断,确保系统引导正常。

assembly8low的博客 584

实现猫眼电影影片浏览效果

前言部分 因为项目要对接猫眼电影,需要做一个和猫眼电影一样的影片选择效果,其实这本篇文章的内容是网上凑出来的。虽说是东拼西凑,但是过程中还是有些收获,毕竟有些东西还是要亲自实践才能深入理解。 不多说先上个效果图吧: 内容部分 实现效果大体分为几部分: 一个横向滚动的列表(RecyclerView) 列表要选中的条目需要居中显示(LinearSnapHelper) 选中的条目需要放大效果(或者把...

鲨鱼不会飞的博客 1249

TSMaster二次开发实战:如何用Python搞定CAN/CANFD事件回调(附完整代码)

本文详细介绍了如何利用Python进行TSMaster二次开发,实现CAN/CANFD事件回调功能。通过实战代码演示,讲解了预发送与后处理回调的核心区别、注册流程、资源管理及性能优化技巧,帮助工程师高效构建自动化测试与数据监控应用。

star的博客 668

BAT031:按列表名单将路径a下的文件夹批量剪切到路径b

摘要:按列表名单将路径a下的文件夹批量剪切到路径b。

qq_31762031的博客 1218

2024年手把手教你用RecyclerView实现猫眼电影选择效果(2),2024年最新字节跳动 算法工程师 面试

总而言之,成功是留给准备好的人的。无论是参加什么面试,都要做好充足的准备,注意好面试的礼仪和穿着,向面试官表现出自己的热忱与真诚就好。即使最后没有过关,也要做好经验的总结,为下一次面试做好充足准备。这里我为大家准备了一些我在面试后整理的面试专题资料,除了面试题,还总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料分享给大家,希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。

2401_84537826的博客 373

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

实现类似猫眼影片详情页电影海报滚动效果(ViewPager 两侧显示相邻item)

本文参考(ViewPager画廊效果)仿淘票票影院影片选择 这种实现方法比较简单,但是并不能像是淘票票、猫眼的电影画廊那样,一下子滚动多个item,因为ViewPager本质上就是一次只能划过一个item(此外这种方法,必须设置所有的条目作为缓存mViewPager.setOffscreenPageLimit(TOTAL_COUNT),这样性能低) 一次划过多个item,需要使用

Android_Study_OK的博客 3743

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

猫眼电影下拉刷新效果实现

无入侵的猫眼下拉刷新,无需重写RecyclerView,像SwipeRefreshLayout一样使用简单 最近在做一个高仿的猫眼App,观察猫眼电影App的下拉刷新后,发现其中还是有小细节的,所以决定自己动手撸了一个猫眼下拉刷新(其实是网上实在没有找到可以抄的代码。。),结合SuperRefreshLayout加上自定义的一个刷新头部达到了猫眼App的下拉刷新效果 先上图 ...

r09er的博客 286

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

RxJava2+Retrofit+MVP高仿猫眼电影(7.9.1)

项目初衷 一直以来看到很多开源项目都是什么MaterialDesign(后面简称MD),但是真的是这样吗,个人觉得这些项目只是为了MD而MD,用几个控件就说自己的是MD风格,写了几个XML就觉得把MD的控件用熟了,如果是这样,我宁愿不用!对于真正是MD的App我只在Google市场和一些真正优秀的开源项目看到过,至于国内的目前我只看到了B站. 为什么不参照一些设计和交互都不错的应用...

r09er的博客 286

Android 猫眼电影那什么网易云 layoutmanager 第二条放大

来几个稀里糊涂的 CV //https://www.jianshu.com/p/ef3a3b8d0a77 //https://www.jianshu.com/p/e54db232df62 1.一次只能最多翻过一页的SnapHelper public class GallerySnapHelper extends SnapHelper { private static fin...

FlyPig_Vip的博客 716

RecyclerView -- 中阶

BRVAH使用多布局 1. 实体类实现MultiItemEntity 接口,根据类型进行绑定; 2. 为 BaseQuickAdapter 设置代理。标题SnapHelper Support RecyclerView 24.2.0中新加,让RecyclerView滑动视图后使停止位置正好停在某页的正中间。new LinearSnapHelper().attachToRecyclerView(r

ThePromonkeyOf_HeLuo的博客 378
上一篇: OpenCV 人脸跟踪
下一篇: 带你理解 Android 消息机制原理
动脑学院[David]
博客等级 码龄8年 44粉丝 31原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值