ScrollRecyclerView——RecyclerView 横向 / 纵向滚动网格布局

今天分享一个自己封装的 RecyclerView 横向 / 纵向滚动网格布局,先来水一水它产生的背景吧 ~ 也许看完下面简单的介绍,你才能大致了解 ScrollRecyclerView 是做什么的,要不然只知道是 RecyclerView 的封装的话,你肯定不会往下看了,因为已经有太多好用的 RecyclerView 封装了......给个机会吧,往下再瞅瞅(⊙o⊙) ~~

由于公司的产品是针对某种特制的 Android 系统设备(14 吋)的定制化研发,前段时间,工厂那边提供了新设备,话说是很多性能方面都有了较大的提升,遥控器也更新了。(⊙o⊙)哦,对了,忘了说,设备是不支持触摸操作的,使用遥控器控制。之前的那款遥控器是内置陀螺仪的,可以模拟用户手指操作,就是说能像操作手机触摸屏那样操作屏幕,而这款遥控器却没有了这项功能,只有普通遥控器的功能了,像电视机遥控器一样,操作起来特别费劲,产品中很多界面操作不便,体验很差。遂今天的主角——ScrollRecyclerView 产生了,希望通过它能改善遥控器操作的使用体验。

ScrollRecyclerView——RecyclerView 横向 / 纵向滚动网格布局,适用于 Android 平板、Android TV 或其他定制化 Android 设备等,使用遥控器方向导航键控制列表滑动及 item 选择状态。

效果预览

ScrollRecyclerView 效果演示

依赖

JitPack 引入方法

1. 在 Project 下的 build.gradle 添加
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
2. 在 Module 下的 build.gradle 添加
dependencies {
    compile 'com.github.lishide:ScrollRecyclerView:v1.0.0'
}

使用

  • 在 xml 中引用 ScrollRecyclerView
<com.lishide.recyclerview.scroll.ScrollRecyclerView
    android:id="@+id/scroll_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
  • 初始化 ScrollRecyclerView,设置布局管理器、间距、适配器、数据等
// 初始化 ScrollRecyclerView
mScrollRecyclerView = (ScrollRecyclerView) findViewById(R.id.scroll_recycler_view);
// 设置动画
mScrollRecyclerView.setItemAnimator(new DefaultItemAnimator());
// 设置布局管理器:瀑布流式
mScrollRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3,
        StaggeredGridLayoutManager.HORIZONTAL));
// 根据需要设置间距等
int right = (int) getResources().getDimension(R.dimen.dp_20);
int bottom = (int) getResources().getDimension(R.dimen.dp_20);
RecyclerView.ItemDecoration spacingInPixel = new SpaceItemDecoration(right, bottom);
mScrollRecyclerView.addItemDecoration(spacingInPixel);
  • 适配器中初始化控件并设置数据

使用的 Adapter 就是正常的 Adapter。为了简单明了,在示例中用的是最普通的一种。当然了,你完全可以使用你常用的或是被封装过的高级 Adapter。

Adapter 中比较重要的是设置 itemView 可以获得焦点,并监听焦点变化。还有要设置 Tag,用来标记 item 的 position,后面有用。

holder.itemView.setFocusable(true);
holder.itemView.setTag(position);
holder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {

    }
});

会发现在 Adapter 中设置了许多监听器,目前有这四个:

  • item 选定监听(OnItemSelectedListener)
  • item 点击监听(OnItemClickListener)
  • item 长按监听(OnItemLongClickListener)
  • 遥控器其他按键监听(OnItemKeyListener)

已将这四个 Listener 放在 lib 中,开发者根据需要直接设置和调用即可。

要想实现咱们今天主要实现的功能——使用遥控器方向导航键控制列表滑动及 item 选择状态,下面的步骤很重要。

  • 在焦点监听器中,判断获得焦点时调用 mOnItemSelectedListener.OnItemSelected(v, currentPosition);,传入 view 和当前 position。
if (hasFocus) {
    currentPosition = (int) holder.itemView.getTag();

    mOnItemSelectedListener.OnItemSelected(v, currentPosition);
}
  • 滑动列表

设置 item 选定监听器,然后在监听器中实现列表滑动。

adapter.setOnItemSelectedListener(mOnItemSelectedListener);
OnItemSelectedListener mOnItemSelectedListener = new OnItemSelectedListener() {
    @Override
    public void OnItemSelected(View view, int position) {
        mScrollRecyclerView.smoothHorizontalScrollToNext(position);
    }
};

实现滑动的功能就是这个smoothHorizontalScrollToNext方法了。

小结:
通常情况,遥控器的上下左右按键的监听系统都处理好了,但是有时候按键处理会出现一下问题:
比如,焦点现在在最后一列的某个 item 上,但这个 item 后面还有很多列,只是此时屏幕上没显示出来,需要向左滚动,才能看到后面的 item,但是此时系统的监听不会自己滚动,并且按下遥控右键不会有反应。这里就需要我们想办法解决一下。

我的思路是这样:
1、由于系统的遥控器方向键监听是需要在当前屏幕上知晓是否后面还有 item 才可以继续按右键的。所以设计一个算法在 ScrollRecyclerView 中,使得焦点到达最右边时,父控件向左边滚出一定距离;而焦点到达最左边时,父控件向右边滚动一定距离。
2.此时再按下方向键,系统又可以使得下一个Item获得焦点了。

具体的实现过程推荐下载 demo 看代码,demo 里面的注释非常全了。

好了,至此 使用遥控器方向导航键控制列表滑动及 item 选择状态 的功能大概完成了。顺便解释一下其他几个 Listener 的作用,OnItemClickListener、OnItemLongClickListener 这两个好理解,在其他的列表点击监听也会遇到过,就不过多说了。需要注意一点的是,item 长按监听要对 view 的点击事件返回值根据需要处理一下,比如 return false 会在长按事件结束后再触发一次点击事件,return true则只会触发长按事件。如果有特定需要,比如焦点在列表的某个 item 上时,按下了 OK 键,需要跳转到一个新的界面;或者按下 Menu 键做其他业务逻辑处理等等,此时应该设置监听——OnItemKeyListener(遥控器其他按键监听)。

ScrollRecyclerView 的用处有一些局限性,手机端应该是用不到(我感觉,因为有触摸屏~),主要适用于 Android 平板、Android TV 或其他定制化 Android 设备等......这里,仍期待得到您的支持!

代码已经开源到 Github:https://github.com/lishide/ScrollRecyclerView

您在使用过程中,发现 bug 或有好的建议欢迎 issue、email (lishidezy@gmail.com),如果感觉对你有帮助也欢迎点个 star,留下点印记吧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容