今天分享一個自己封裝的 RecyclerView 橫向 / 縱向滾動網格布局,先來水一水它產生的背景吧 ~ 也許看完下面簡單的介紹,你才能大致了解 ScrollRecyclerView 是做什么的,要不然只知道是 RecyclerView 的封裝的話,你肯定不會往下看了,因為已經有太多好用的 RecyclerView 封裝了......給個機會吧,往下再瞅瞅(⊙o⊙) ~~
由于公司的產品是針對某種特制的 Android 系統設備(14 吋)的定制化研發,前段時間,工廠那邊提供了新設備,話說是很多性能方面都有了較大的提升,遙控器也更新了。(⊙o⊙)哦,對了,忘了說,設備是不支持觸摸操作的,使用遙控器控制。之前的那款遙控器是內置陀螺儀的,可以模擬用戶手指操作,就是說能像操作手機觸摸屏那樣操作屏幕,而這款遙控器卻沒有了這項功能,只有普通遙控器的功能了,像電視機遙控器一樣,操作起來特別費勁,產品中很多界面操作不便,體驗很差。遂今天的主角——ScrollRecyclerView 產生了,希望通過它能改善遙控器操作的使用體驗。
ScrollRecyclerView——RecyclerView 橫向 / 縱向滾動網格布局,適用于 Android 平板、Android TV 或其他定制化 Android 設備等,使用遙控器方向導航鍵控制列表滑動及 item 選擇狀態。
效果預覽
依賴
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,留下點印記吧。