前言
最近在寫AndroidTV的項目懊缺,遇到一個實現(xiàn)類似于移動端拖拽移動的效果,如下圖所示鸵隧。
1.gif
TV與手機端最大的不同在手機是觸控的,TV需要獲取焦點意推。研究了一下豆瘫,手機端是通過
RecyclerView
和itemTouchHelper
來實現(xiàn)這個效果的。那么TV該如何實現(xiàn)這個效果呢菊值?
實現(xiàn)
在TV端雖然也可以使用RecyclerView
外驱,但是VerticalGridView
和HorizontalGridView
才是谷歌推薦在TV使用的。因此腻窒,我們把目標放在這兩個控件當中昵宇。小編這里使用的是VerticalGridView
控件,布局文件就不粘貼了儿子,完整代碼可以拉到最下方瓦哎。
實現(xiàn)這個功能分為兩步:
自定義VerticalGridView
并重寫focusSearch
方法,focus
變化時觸發(fā)位置互換;
ArrayObjectAdapter 中調(diào)用Moved
實現(xiàn)數(shù)據(jù)更新杭煎。
public View focusSearch(View focused, int direction) {
View itemView = findContainingItemView(focused);
if (itemView != null && isSwapMode()) {
return swapItemsIfNeeded(itemView, direction);
}
return super.focusSearch(focused, direction);
}
private View swapItemsIfNeeded(View focused, int direction) {
int position = getChildAdapterPosition(focused);
ItemAnimator animator = getItemAnimator();
if ((animator == null || !animator.isRunning())
&& canMoveInDirection(position, direction)) {
int spanCount = getSpanCount();
switch (direction) {
case FOCUS_LEFT:
moveItem(position, position - 1);
break;
case FOCUS_UP:
moveItem(position, position - spanCount);
break;
case FOCUS_RIGHT:
moveItem(position, position + 1);
break;
case FOCUS_DOWN:
moveItem(position, position + spanCount);
break;
default:
break;
}
}
return focused;
}
private boolean canMoveInDirection(int position, int direction) {
int spanCount = getSpanCount();
LayoutManager m = getLayoutManager();
assert m != null;
if (direction == FOCUS_LEFT) {
return position % spanCount > 0;
} else if (direction == FOCUS_UP) {
return position - spanCount >= 0;
} else if (direction == FOCUS_RIGHT) {
return !(position % spanCount >= (spanCount - 1) ||
position >= m.getItemCount() - 1);
} else if (direction == FOCUS_DOWN) {
return position + spanCount <= m.getItemCount() - 1;
}
return false;
}
private void moveItem(int fromPosition, int toPosition) {
if (adapter != null) {
adapter.move(fromPosition, toPosition);
}
}
這篇文章到這里就結(jié)束了,寫的不好的地方歡迎大家指出卒落,Demo下載地址:Demo羡铲。最后,希望這篇文章對各位看官們有所幫助儡毕。如果看官們可以給小編一個小小的支持那就更好了也切。
參考
https://stackoverflow.com/questions/54236100/how-do-i-move-grid-items-on-android-tv
https://www.mi-dong.com/post/android/android-tv-recyclerview-item-move/
https://blog.51cto.com/u_12855/6662173