Android添加item动画,RecyclerView基础篇-Item添加动画

4c1eb409bc0e

Android_Banner.jpg

简介

本节中我们介绍下给RecyclerView中的Item添加动画。

添加的动画,分为,在打开列表时有Item的展示动画,当滑动的时候没有动画

和打开列表滑动时有动画两种

实现过程

实现一个列表

效果如下

4c1eb409bc0e

Screenshot_2020-09-01-17-03-35-349_com.dashingqi.module.recyclerview.png

接下来我们就要操作这个列表中的Item,让其产生动画

布局的实现代码

main_activity.xml 的布局文件

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools">

name="viewModel"

type="com.dashingqi.module.recyclerview.RvAnimationViewModel" />

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".RvAnimationActivity">

android:id="@+id/animRv"

android:layout_width="match_parent"

android:layout_height="match_parent"

app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

MainActivity.kt中的代码

lass RvAnimationActivity : AppCompatActivity() {

private val animationDownToUp by lazy {

AnimationUtils.loadAnimation(this, R.anim.item_anim_down_to_up)

}

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

val dataBinding = DataBindingUtil.setContentView(

this,

R.layout.activity_rv_animation

)

//获取到ViewModel的实例

val viewModel = ViewModelProvider(this)[RvAnimationViewModel::class.java]

//绑定ViewModel

dataBinding.viewModel = viewModel

//设置适配器

var adapter = RvAnimationAdapter(viewModel.items, animRv)

animRv.adapter = adapter

// 为Rv中的Item添加装饰器

animRv.addItemDecoration(object : RecyclerView.ItemDecoration() {

override fun getItemOffsets(

outRect: Rect,

view: View,

parent: RecyclerView,

state: RecyclerView.State

) {

val childPosition = parent.getChildAdapterPosition(view)

if (childPosition != 0) {

outRect.top = DensityUtils.dip2pxInt(parent.context, 16f)

}

}

})

}

}

ViewModel中的代码

class RvAnimationViewModel : ViewModel() {

val items = ObservableArrayList()

val itemBinding = ItemBinding.of(BR.item, R.layout.item_anim_view)

init {

for (index in 0 until 80) {

items.add("Item${index}")

}

}

}

Adapter中的代码

class RvAnimationAdapter(var datas: ArrayList, var recyclerView: RecyclerView) :

RecyclerView.Adapter() {

class MyViewHolder(var dataBinding: ItemAnimViewBinding) :

RecyclerView.ViewHolder(dataBinding.root) {

}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

val dataBinding = DataBindingUtil.inflate(

LayoutInflater.from(parent.context),

R.layout.item_anim_view,

parent,

false

)

return MyViewHolder(dataBinding)

}

override fun getItemCount(): Int {

return datas.size

}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {

val itemDataBinding = holder.dataBinding as ItemAnimViewBinding

itemDataBinding.item = datas[position]

itemDataBinding.executePendingBindings()

}

}

item的布局文件

xmlns:app="http://schemas.android.com/apk/res-auto">

name="item"

type="String" />

android:layout_width="match_parent"

android:layout_height="wrap_content">

android:layout_width="match_parent"

android:layout_height="240dp"

android:background="@android:color/holo_red_dark"

android:text="@{item}"

android:gravity="center"

android:textColor="#ffffff"

android:textSize="20sp"

android:textStyle="bold"

app:layout_constraintTop_toTopOf="parent" />

实现进入列表时的动画

实现效果如下

4c1eb409bc0e

list_start.gif

该动画是从右侧平移到屏幕中,所以我们的平移动画的X轴的起点从 100%开始,终止点为0 ,y不变

android:duration="500">

android:fromXDelta="100%p"

android:fromYDelta="0"

android:toXDelta="0"

android:toYDelta="0" />

android:fromAlpha="0"

android:toAlpha="100" />

接着借助LayoutAnimationController 给 RV的layoutAnimation设置动画数据

val viewModel = ViewModelProvider(this)[RvAnimationViewModel::class.java]

dataBinding.viewModel = viewModel

var adapter = RvAnimationAdapter(viewModel.items, animRv)

animRv.adapter = adapter

var animation = AnimationUtils.loadAnimation(this, R.anim.item_anim_translate)

val layoutAnimationController = LayoutAnimationController(animation)

//设置顺序

layoutAnimationController.order = LayoutAnimationController.ORDER_NORMAL

animRv.layoutAnimation = layoutAnimationController

滑动的时候带有动画

效果如下

4c1eb409bc0e

list_scroll.gif

上图中的效果,是在ItemView可见的时候执行动画,我们的切入点也就是这个时机,正好Adapter中有提供一个方法onViewAttachedToWindow()

onViewAttachedToWindow() 是当Adapter创建好的View依附在Window的时候调用的,所以这个方法是一个时机,在这个方法中,为每一个ItemView设置动画。

同时我们还需要为Rv设置滑动的监听事件,来记录滑动的方向,这样在onViewAttachedToWindow()方法中设置不同的动画

所以Adapter中的代码变更如下

class RvAnimationAdapter(var datas: ArrayList, var recyclerView: RecyclerView) :

RecyclerView.Adapter() {

/**

* 用来记录当前是向上滑动的

*/

var isScrollUp = false

/**

* 用来记录当前是向下滑动的

*/

var isScrollDown = false

/**

* 动画

*/

private val animation by lazy {

AnimationUtils.loadAnimation(recyclerView.context, R.anim.item_anim_translate)

}

private val animationUpToDown by lazy {

AnimationUtils.loadAnimation(recyclerView.context, R.anim.item_anim_up_to_down)

}

private val animationDownToUp by lazy {

AnimationUtils.loadAnimation(recyclerView.context, R.anim.item_anim_down_to_up)

}

init {

//为RV添加滑动事件的监听

recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {

override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {

super.onScrollStateChanged(recyclerView, newState)

}

override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {

super.onScrolled(recyclerView, dx, dy)

isScrollUp = dy > 0

isScrollDown = dy < 0

}

})

}

class MyViewHolder(var dataBinding: ItemAnimViewBinding) :

RecyclerView.ViewHolder(dataBinding.root) {

}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

val dataBinding = DataBindingUtil.inflate(

LayoutInflater.from(parent.context),

R.layout.item_anim_view,

parent,

false

)

return MyViewHolder(dataBinding)

}

override fun getItemCount(): Int {

return datas.size

}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {

val itemDataBinding = holder.dataBinding as ItemAnimViewBinding

itemDataBinding.item = datas[position]

itemDataBinding.executePendingBindings()

}

/**

* 当创建好的View依附到Window上时回调的

*/

override fun onViewAttachedToWindow(holder: MyViewHolder) {

super.onViewAttachedToWindow(holder)

for (index in 0 until recyclerView.childCount) {

//获取到Item

val itemView = recyclerView.getChildAt(index)

//清除每一个Item上的动画

itemView?.clearAnimation()

}

// 当向上滑动的时候

if (isScrollUp) {

holder.itemView.startAnimation(animationDownToUp)

}

//当向下滑动的时候

if (isScrollDown) {

holder.itemView.startAnimation(animationUpToDown)

}

}

}

对应的动画文件

android:duration="200">

android:fromYDelta="100%"

android:toYDelta="0" />

android:fromAlpha="0"

android:toAlpha="1" />

android:duration="200"

>

android:fromYDelta="-100%"

android:toYDelta="0" />

android:fromAlpha="0"

android:toAlpha="1" />

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/278911.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle数据库查询用 where in 查询的项超过1000条的解决方案

众所周知&#xff0c;如果我们的用SQL查询语句时&#xff0c;如果用where in带的参数超过1000条的话&#xff0c;oracle是会报错的。 因为项目中遇到这样的问题&#xff0c;所以找到了接下来我要说的这个办法。 因为用的地方很多&#xff0c;所以我把这个封装成了一个方法。 //…

geek_Ask How-To Geek:营救受感染的PC,安装无膨胀iTunes和驯服疯狂的触控板

geekYou’ve got questions and we’ve got answers. Today we highlight how to save your computer if it’s so overrun by viruses and malware you can’t work from within Windows, install iTunes without all the bloat, and tame a hyper-sensitive trackpad. 您有问…

第1课:接口测试和jmeter总结

接口测试 1. 接口的分类&#xff1a;webService和http api接口1&#xff09; webService接口&#xff1a;是按照soap协议通过http传输&#xff0c;请求报文和返回报文都是xml格式&#xff0c;一般要借助工具来测试接口&#xff1b;2&#xff09; http api接口&#xff1a;是按照…

android 工作日,如何在Android上重复警报工作日

小编典典请尝试此代码。已在我的应用中成功运行if (chk_monday.isChecked()) {forday(2);} else if (chk_tuesday.isChecked()) {forday(3);} else if (chk_wednesday.isChecked()) {forday(4);} else if (chk_thursday.isChecked()) {forday(5);} else if (chk_friday.isCheck…

hdu4419

对于这类面积覆盖的题&#xff0c;大致就两点要注意的 1.同一把矩形放在笛卡尔坐标系上做 2.pushup函数要注意下细节:及在统计子区间和之前要先判断是否有子区间 用sum数组来保存区间被覆盖的情况&#xff0c;如果遇到多次覆盖问题&#xff0c;那就开多个sum数组分别保存被覆盖…

最简单 - 单例模式

public class Person {// Person 引用private static Person p null;static {if (p null) {p new Person();}}/***单例模式获取Person对象. * return*/public static Person getInstance(){return p;} ​} 复制代码转载自&#xff1a; 简书 - 低至一折起 文章&#xff1a;w…

极客时间和极客学院_极客历史记录的本周:Twitter的诞生,OS X十周年以及太空停留时间最长的时代即将结束...

极客时间和极客学院Every week we bring you interesting trivia and milestones from the archives of Geekdom. Today we’re taking a peek at the birth of Twitter, ten years of Mac OS X, and the longest space stay in history. 每周&#xff0c;我们都会为您带来有趣…

Android风格ppt,Material Design风格的快手PPT

突发奇想&#xff0c;感觉MD风格既然适合 Android 软件的界面&#xff0c;那么在一般PPT 演示中&#xff0c;效果当也是不错。于是在网上去寻了几处制作贴&#xff0c;也简单看了 MD 设计指南的几处要点。先试试一番再说。关于 MD 设计指南和几处制作贴&#xff0c;我会把链接贴…

11月16日站立会议

今天是冲刺阶段的第二天&#xff0c;我今天做了统计在线人数模块的编写而且对其进行了测试并修改完成&#xff0c;为团队制作了今日的燃尽图。 明天我要完成服务器端可以断开所有用户连接的一个小模块和继续为团队制作燃尽图。 今天遇到的困难是用Java进行编写时&#xff0c;出…

iOS核心动画高级技术(十三) 高效绘图

More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason—including blind stupidity. 不必要的效率考虑往往是性能问题的万恶之源。 ——William Allan Wulf #软件绘图 术语绘图通常在Core Anima…

dropbox链接过期_询问操作方法:“开始”菜单中的Dropbox,了解符号链接和翻录TV系列DVD...

dropbox链接过期This week we take a look at how to incorporate Dropbox into your Windows Start Menu, understanding and using symbolic links, and how to rip your TV series DVDs right to unique and high-quality episode files. 本周&#xff0c;我们来看看如何将D…

android listpreference 自定义,Android – 我的ListPreference中的自定义行布局

在我的Android应用程序中,我实现了从ListPreference扩展的类SubtitleColorListPreference.我需要这个,因为我需要为列表中的每个项目设置自己的布局.一切正常,它看起来像这样&#xff1a;重要的代码是onPrepareDialogBu​​ilder(AlertDialog.Builder builder)中的方法,我在其中…

springMVC3学习(十一)--文件上传CommonsMultipartFile

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主同意不得转载。 https://blog.csdn.net/itmyhome/article/details/27976873 使用springMVC提供的CommonsMultipartFile类进行读取文件须要用到上传文件的两个jar包 commons-logging.jar、commons-io-xxx.jar1、在sp…

基于React和SpringBoot的快速开发模板QuickAdmin

经过一段时间的总结和完善&#xff0c;我的管理系统快速开发模板已经基本成型&#xff0c;现在GitHub上开源啦&#xff1a; QuickAdmin QuickAdmin是基于Spring Boot和React.js实现的管理系统开发框架。用于开发网站的后台管理系统。 本框架提供了如下功能&#xff1a; 完整的基…

android sim iso,android – 意外的telephonyManager.getSimCountryIso()行为

您可以使用MCC MNC获取SIM卡国家/地区,它是SIM配置的,与您所在的网络无关.Configuration config getResources().getConfiguration();int countryCode config.mcc;您可以在此处找到MCC列表MccTable.java例如,西班牙是214,法国是208MCC should work on all GSM devices with S…

火狐 增强查找工具栏_在“提示”框中:简单的IE至Firefox同步,轻松的Windows工具栏和识别USB电缆...

火狐 增强查找工具栏() Every week we tip into our mail bag and share great tips from your fellow readers. This week we’re looking at an easy way to sync your bookmarks between IE and Firefox, using simple Windows toolbars, and a clever way to ID USB cables…

day22 模块-collections,time,random,pickle,shelve等

一、引入模块的方式: 1. 认识模块 模块可以认为是一个py文件. 模块实际上是我们的py文件运行后的名称空间 导入模块: 1. 判断sys.modules中是否已经导入过该模块 2. 开辟一个内存 3. 在这个内存中执行该py文件 4. 给这个内存起个名字&#xff0c; 一般用的是py文件的名字。返回…

基于Redis实现分布式锁,避免重复执行定时任务

Spring提供了定时任务的功能&#xff0c;但是在多个实例的集群中&#xff0c;会出现定时任务重复执行多次的情况。 使用Qutaz框架自带的分布式定时任务可以很好的解决这个问题&#xff0c;但是讲道理功能有些过于强大&#xff0c;对于需求不高&#xff0c;乃至可以一定程度上允…

Input Director使用一个键盘和鼠标即可控制多台Windows计算机

The problem is having two or more PC’s and having to go back and forth between workstation. Input Director solves the problem by allowing you to control multiple Windows systems with only one keyboard and mouse on the Master PC. 问题是拥有两台或更多台PC…

viper4android 生效,另一种让V4a音效在Poweramp上生效的方法

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼本人按照网上的方法进Poweramp设置—音频—高级选项—直接音量控制—不打勾后 V4a音效没有生效 我又把V4a音效兼容模式里的正常模式切换成为兼容模式 结果还是不行......后来我郁闷了三天三夜有一天我去了v4a官网论坛看到了admin帖…