RecyclerView控件的使用及子Item移动居中的实现(TV向)

一、RecyclerView介绍及简单使用

RecyclerView:一种灵活的循环视图,在一个有限的窗口中显示大量的数据集.

1、提供的常用方法

  • setAdapter:设置列表项的适配器。(适配器采用RecyclerView.Adapter)
  • setLayoutManager:设置列表项的布局管理器,包括线性布局管理器LinearLayouManager、网格布局管理器GridLayouManager、瀑布流布局管理器StaggeredGridLayouManager。
  • addItemDecoration:添加列表项的分割线。
  • removeItemDecoration:移除列表项的分割线。
  • setItemAnimator:设置列表项的增删动画。默认动画可是由于系统自带的DefaultItemAnimator。
  • addOnItemTouchListener:添加列表向的触摸监听器。
  • removeOnItemTouchListener:移除列表向的触摸监听器。

2、数据适配器

RecyclerView有专门的适配器类——RecyclerView.Adapter。在调用setAdapter前需要实现一个从RecyclerView.Adapter派生出来的数据适配器,用来定义列表项的布局与具体操作。

RecyclerView.Adapter相关的常用方法:

(1)自定义适配器必须要重写的方法:

  • getItemCount:获取列表项的数目。
  • onCreateVierwHolder:创建整个布局的视图持有者,输入参数中包括视图类型,可根据视图类型加载不同的布局,从而实现带头部的列表布局。
  • onBindViewHolder:绑定每项的视图拥有者。

(2)可以重写也可以不重写的方法:

  • getItemViewViewType:返回每项的视图类型。这列返回的视图类型供onCreateVierwHolder方法使用。
  • getItemId:提供每项的编号。

(3)可以直接调用的方法:

  • scrollToPosstion:滚动到指定位置。
  • notifyItemInserted:通知适配器在指定位置已插入新项。
  • notifyItemRemoved:通知适配器在指定位置已删除。
  • notifyItemChanged:通知适配器在指定位置已变化。
  • notifyDataSetChanged:通知适配器整个列表的数据发生变化。

3、布局管理器LayoutManager

布局管理器LayoutManager是RecyclerView的精髓,也是RecyclerView强悍的源泉。LayoutManager不仅提供了3类布局管理,分别实现了列表视图、网络视图、瀑布流网络的效果,而且在代码中随时可以调用setLayoutManager方法设置新的布局。一旦调用了setLayoutManager方法,界面就会根据新的布局刷新列表项。这个特性特别适合用于手机在横屏与竖屏之间的切换显示,也适用于不用屏幕分辨率(如手机与平板)的显示切换(如在手机中显示列表,在平板上显示网路)。

(1)线性布局管理器LinearLayoutManager

LinearLayoutManager类似与线性布局LinearLayout,在垂直方向布局时,展示效果类似于垂直的列表视图以ListView;在水平布局时,类似于水平方向的列表视图。

常用方法:

  • 构造函数:可指定列表的方向和是否为相反方向开始布局。
  • setOrientation:设置列表的方向。可取值LinearLayoutManager.HORIZONTAL或LinearLayoutManager.VERTICAL。
  • setReverseLayout:设置是否为相反方向开始布局,默认false。

例子:

 LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);layoutManager.setOrientation(RecyclerView.HORIZONTAL);mRecyclerView.setLayoutManager(layoutManager);

效果:

(2)网格布局管理器GridLayoutManager

其类似于网格布局GridLayout,把GridLayoutManager当作GridView一样使用就行。

常用方法:

  • 构造函数:可指定网格的列数。
  • setSpanCount:设置网格的列数。
  • setSpanSizeLookup:设置列表项的占位规则。默认一项占一列,如果想某项占多列,就可以在此设置自定义的占位规则,即由GridLayoutManager.SpanSizeLookup派生具体的实现类。

例子:

  GridLayoutManager layoutManager = new GridLayoutManager(MainActivity.this,3);
//        layoutManager.setOrientation(RecyclerView.HORIZONTAL);  也能设置横向滚动mRecyclerView.setLayoutManager(layoutManager);

效果:

(3)瀑布流网络布局管理器StaggeredGridLayoutManager

电商APP在展示众多商品信息时,往往使用灵活高度的各自展示。因为不同商品的外观尺寸不一样,比如冰箱高高的纵向比较长,空调横向比较长,所以若用一样规格的网格展示,必然有的商品图片会被压缩得很小。这种情况得根据不同得商品形状展示不同高度的图片,这就是瀑布流网络布局管理器的应用场景。StaggeredGridLayoutManager让瀑布流效果的开发大大简化了,只要在适配器中动态设置每个网格的高度,系统就会在界面上依次列表排列瀑布流网格。

常用方法:

  • 构造函数:可设置网格的列数与方向。
  • setSpanCount:设置网格的列数。
  • setOrientation:设置瀑布流布局的方向。
  • setReverseLayout:设置是否为相反方向开始布局。

二、RecyclerView子Item移动居中的实现(TV列表移动规则的实现)

首先让我们规范焦点移动的规范:焦点在界面上的移动路径一内容翻页时的焦点移动路径。

A、纵向单行列表
在电视界面内,焦点随着用户点击遥控器的方向键而移动,移动到单行列表边缘位置时,仍继续向屏幕可是区域外移动。

  • 当列表内容超过一屏,焦点固定居中,内容项反向移动。
  • 列表内容不足一屏时,焦点可移动到列表的最后一个选项。

    B、横向单行列表
  • 焦点移动到列表边缘位置仍继续向屏幕可视局域外移动,当列表内容超过一屏,焦点固定居中,内容项反向移动。
  • 列表内容不足一屏时,焦点可移动到列表的最后一个选项。

解决方案:重写RecyclerView

RecyclerView原生接口的焦点移动机制是:

  • 焦点默认处于第一个子Item上,焦点移动时,移动到下一个Item上。
  • 当通过按键控制焦点移动时,列表内容不足一屏时,焦点可移动到列表的最后一个选项,当列表内容超过一屏,焦点处于屏幕中最后一个完全可见的子Item上,内容项反向移动至最后一个。

要实现我们想要达成的移动效果,我的想法是:运用RecyclerView本身的焦点自动移动到下一个的特点,当焦点移动后去根据子Item的序号去判断是否需要焦点固定,当焦点需要在固定位置时,采用滑动方式移动,当焦点不需要固定时,恢复默认方式。

1、如何保证平滑滚动

我的方案是利用RecyclerView的方法smoothScrollToPosition(int position),该方法的功能描述是:

Starts a smooth scroll to an adapter position.(平滑滚动到某个适配器位置。

参数:int position:期许平滑滚动到的子Item的序号

2、如何实现焦点规范

其实横向与竖向规范我们可以进行统一,将横向向左移动和竖向向上移动、横向向右移动和竖向向下移动当做同一事件。

我们以处理横向向右移动为例进行分析:
首先我们需要知道当前Item的序号,因为我们是重写的RecyclerView,所有不能去要求传入position,此时我们利用:

View view = getFocusedChild();
int position = getChildAdapterPosition(view);

获取当前序号。

获取平滑参数:

     //获取第一个完全可见的Itemint firstCompletelyVisibleItemPosition = ((LinearLayoutManager)getLayoutManager()).findFirstCompletelyVisibleItemPosition();//获取最后一个完全可见的Itemint lastCompletelyVisibleItemPosition = ((LinearLayoutManager)getLayoutManager()).findLastCompletelyVisibleItemPosition();//可见控件数量int childCount = getChildCount();//不出意外,都是从第0个Item进行移动,所有在此对平滑参数进行初始化。if (firstCompletelyVisibleItemPosition == 0) {temp = childCount / 2;//temp为平滑参数}   //防止用户自定义焦点初始所在位置,导致temp=0if (temp ==0) {temp = childCount / 2;}

当我们获取了平滑参数和当前位置之后,我们就需要判断焦点移动形式了。

 if (firstCompletelyVisibleItemPosition == 0&& position < temp) {smoothScrollToPosition(position + 1);} else {if (position == this.getAdapter().getItemCount() - 1) {return;} else {if (lastCompletelyVisibleItemPosition == this.getAdapter().getItemCount() - 1&& position > lastCompletelyVisibleItemPosition - temp) {smoothScrollToPosition(position + 1);} else {smoothScrollToPosition(position + temp);}}}

这样整体就完成了横向右滑的功能,左滑功能与其类似。

3、添加按键响应

重写RecyclerView的dispatchKeyEvent方法;

 //判断布局方向protected void initOrientation(){this.Orientation = ((LinearLayoutManager)getLayoutManager()).getOrientation();}@Overridepublic boolean dispatchKeyEvent(KeyEvent event) {initOrientation();try {if (this.Orientation == 0){if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT&& event.getAction() == KeyEvent.ACTION_DOWN) {smoothToCenterRight();}if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT&& event.getAction() == KeyEvent.ACTION_DOWN) {smoothToCenterLeft();}} else {if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN&& event.getAction() == KeyEvent.ACTION_DOWN) {smoothToCenterRight();}if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP&& event.getAction() == KeyEvent.ACTION_DOWN) {smoothToCenterLeft();}}}catch (Exception e){e.printStackTrace();}return super.dispatchKeyEvent(event);}

注意:
1、event.getAction() == KeyEvent.ACTION_DOWN 是为了防止按键响应两次。
2、必须用try{}catch()包裹,防止长按按键时出现崩溃情况。

Demo下载

4、其他解决方法

(1)其实当我们去查看RecyclerView.smoothScrollToPosition方法时,我们会发现其调用的是LayoutManager的方法,我们也可以通过自定义布局管理器的方式来达到相应的效果。

(2)或者重写RecyclerView的requestChildFocus和requestChildRectangleOnScreen方法,直接在子Item获得焦点时处理事件。

RecyclerView控件的使用及子Item移动居中的实现(TV向)相关推荐

  1. Android初学二之仿微信APP实现RecyclerView控件的设计开发,实现点击事件及图片瀑布流

    目录 0 实验环境 1 界面展示 2 功能说明 3 核心代码 3.1 实现RecyclerView控件的设计开发 3.2 添加了文字库assets 3.3 实现点击事件对item中的每个LinearL ...

  2. android 控件覆盖关系,安卓子控件抢占父控件点击事件或者焦点问题

    开发中很常见的一个问题,项目中的lListview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现 ...

  3. RecyclerView控件实现横向滚动和瀑布流布局,以及RecyclerView的点击监听(项目已上传GitHub)

    先附上我的GitHub项目地址: https://github.com/Skymqq/RecyclerViewTest.git 我们已经知道,ListView的拓展性不好,它只能实现纵向的滚动的效果, ...

  4. RecyclerView控件的基本使用(增强版的ListView)

    ListView由于其强大的功能,在过去的Android开发当中可以说是贡献卓越,直到今天仍然还有不计其数的程序在继续使用着ListView.不过ListView并不是完全没有缺点的,比如说如果我们不 ...

  5. Android 高级编程 RecyclerView 控件的使用

    RecyclerView 是Android 新添加的一个用来取代ListView的控件,它的灵活性与可替代性比listview更好. 看一下继承关系: ava.lang.Object    ↳ and ...

  6. 在access窗体中加图片_Access实战:一种不用按钮控件就能控制子窗体联动的方法...

    近来宇哥潜心研究Access的设计,多有心得,在此共享一二.Access窗体若要进行控制,是需要通过按钮控件的,我经过自己探索,发现了一种更加简单的方法,也就是不用控件,通过直接点击窗体已有的表格,就 ...

  7. 在子线程中更改主线程中的控件的信息,在子线程中用toast

    一丶在子线程中不允许更改主线程中的控件的信息,也不允许在子线程中用toast,我们要更改的话 (1)消息机制:使用handler (由主线程调用) 在主程序中Handler handler = new ...

  8. 报表控件NCreport教程:子查询系统设计

    数据报表中经常需要用到主从数据关系,比如发票.订单等一类的特殊文件,在报表控件NCreport中也不例外.数据报表至少有一个表头和一个通过 主键和外键关联的相关细节数据集.子查询系统则是通过父数据源驱 ...

  9. Repeater控件动态变更列(Header,Item和Foot)信息

    需求开发一个小报表,显示最近五个月的summary的数量统计,报表会随月份的变化而变化,如下图.第一列[Department]固定,第二至第六列,也就是说Nov 2012 这列会在下月的时候消失,其后 ...

最新文章

  1. 推荐一位资深 Python 大佬
  2. 2020年中国.NET开发者大会第二天 WorkShop
  3. STL中bitset的用法的整理
  4. python函数作用域与闭包_python函数名称空间与作用域、闭包
  5. 【高级】小程序 - 腾讯云 - wafer - PHP - 数据库接口的应用和研究 - 02 - DB::select - 正确的接口写法 - 包括布尔判断
  6. 论文笔记——DenseNet
  7. 让ListView中的控件失去焦点:android:descendantFocusability=blocksDescendants
  8. python程序下载腾讯企业邮箱附件_python收取邮件(腾讯企业邮箱)
  9. 360os比android,手机系统比拼360OS、Flyme究竟哪个好?
  10. DOS的古董美(未完待續)
  11. 博士生学历真的很重要吗?
  12. “茴”字有四种写法,广发有三种分期;你都知道吗?
  13. 淡泊明志,宁静致远。「学会做人的涵养」 - Qzone日志
  14. DOS命令关机小程序
  15. 如何写出一篇高质量的数据分析报告?
  16. 2009年1月高等教育国际金融全国统一命题考试
  17. SpringBoot爬虫
  18. 示例-Luat示例-MQTT
  19. leetcode954.二倍数对数组C++(绝对值排序)
  20. 剑~~~~~~~~~~

热门文章

  1. Java/可逆素数/个税查询/求前N天
  2. math的向上取整_JavaScript数字向上取整:Math对象的ceil()方法
  3. 电力系统【第5章:电力系统的有功功率和频率调整】
  4. Keil代码格式对齐
  5. 什么是净利润(亿)?
  6. scanf函数的用法
  7. 【工具】各种图中各种图形都代表什么含义
  8. 详解line-height与vertical-algin
  9. 智慧园区解决方案,快递管家助力达实大厦快递物流管理数智化升级
  10. 微型计算机系统中 麦克风属于,2017年一级计算机考试选择题