我是靠谱客的博主 心灵美机器猫,这篇文章主要介绍Android TV开发经验总结---控件Gridview使用,现在分享给大家,希望可以做个参考。

    前一篇我们已经讲解的基本Android TV 开发的基础技能Android TV开发经验总结---初识TV开发,接下来聊聊TV开发中所涉及到的控件运用

    目前Android TV 开发的资料不是蛮多,经过一系列的搜索,目前比较适用的框架推荐 

     冰雪情缘TV / Android-TV-Frame    项目地址:https://git.oschina.net/hailongqiu/AndroidTVWidget

     在我们TV开发中用到最多的可能就是网格和列表了,今天我们先讲讲GridView,有人就会想现在不都是在用recyclerview吗? 但是我告诉你,在TV开发中目前如果不使用google自己的LeackbackTV框架的话目前的原生recyclerview在开发中你会发现,上下左右快速滑动的时候焦点不能预期的达到效果,当然后面我会讲解recyclerview在开发过程中的使用

     系统中的原生GridView在开发过程中会出现哪些问题呢,我们又可以怎么解决?

     首先为了让GridView能够上下左右焦点位置不乱跑,我使用的是Androd-tv-frame中的GridViewTV控件,具体代码请看上面连接中的源码

     然后在使用GridView过程中一般需要用到的监听事件

     gridView.setOnItemSelectedListener     选中事件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<pre name="code" class="java"> //选中事件 gridView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){ @Override public void onItemSelected (AdapterView < ? > parent, View view,int position, long id){ curposition = position; } @Override public void onNothingSelected (AdapterView < ? > parent){ } }); //点击事件 gridView.setOnItemClickListener(new AdapterView.OnItemClickListener(){ @Override public void onItemClick (AdapterView < ? > parent, View view,int position, long id){ } }); //是否获取焦点事件 gridView.setOnFocusChangeListener(new View.OnFocusChangeListener(){ @Override public void onFocusChange (View view,boolean b){ } });


复制代码
1

复制代码
1

        此处需要特别说明的是    gridView.setFocusable(true);   改变控件是否可以获得焦点,然而同时会触发 setOnFocusChangeListener事件 

        在GridView开发过程中还有很坑爹的问题,GridView在初始化或者重新setAdapter后在4.3版本以上会抢焦点默认选中第一个Item ,不光是GridView listview也是如此的情况,所以要避免这种情况的话需要给gridView.setFocusable(false)使得gridview不能抢焦

       其实在开发中如果在4.3版本一下你需要默认第一个Item也是有方法的,可以看看

GridView第一次选中不调用onItemSelected()的解决办法    利用反射促使第一次也调用

      接着说说我们在GridView开发中需要判断是否焦点在Item边缘地带了可以使用如下方法做判断,仅供参考需要自己完善自己逻辑
      
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/** * 判断当前选中的位置在屏幕中的相对位置 * * @param * @return */ public static final int LEFT = 0; public static final int RIGHT = 1; public static final int BOTTOM = 2; public static final int TOP = 3; public int getGridSelectionState() { int selection = gridView.getSelectedItemPosition(); int total = mLiveData.size(); if (total <= 0) { return -1; } if(selection<gridView.getNumColumns()){ return TOP; } if (selection + gridView.getNumColumns() >= total) { return BOTTOM; } if (selection % gridView.getNumColumns() == 0) { return LEFT; } else if (selection % gridView.getNumColumns() == gridView.getNumColumns()-1) { return RIGHT; } else { return -1; } }
       如果这时候你还需要通过方向来确定的话可以使用如下代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private int direction = -1; @Override public boolean dispatchKeyEvent(KeyEvent event) { switch (event.getKeyCode()) { case KeyEvent.KEYCODE_DPAD_LEFT: direction = 1; break; case KeyEvent.KEYCODE_DPAD_RIGHT: direction = 2; break; case KeyEvent.KEYCODE_DPAD_UP: direction = 3; break; case KeyEvent.KEYCODE_DPAD_DOWN: direction = 4; break; default: direction = -1; break; } return super.dispatchKeyEvent(event); }

     有的时候我们需要分页加载数据怎么办,我的思路是判断当前选中的Item的位置是否在最底下,如果是就进行网络请求,在页面的OnkeyDown事件中监听,其实将逻辑封装在自定义Gridview中然后暴露回调接口出来
    
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_DPAD_DOWN: if (isGridFoucse) { //<isGridFoucse标示Gridview是否获取了焦点 if (getGridSelectionState() == BOTTOM && isHaveMore) { //翻页 //TODO:加载数据 return true; } } break; } return false; }

 接着可能就是选中放大的效果了,之前我一直使用的还是上面框架中的放大效果,移动放大框效果很给力,只是在过程中你特别需要注意设置两个属性

android:clipToPadding="false"    android:clipChildren="false"    具体有什么用处你可以问问度娘,会解释的很清楚。

但是由于后期配合项目整体UI的要求,框架不适合,那么又如何有放大选中的效果呢,我的思路是设置Item放大后的背景,先隐藏当选中的时候对View进行放大正好是背景的大小,这就需要我们自己计算Item的宽高了,给个我实现的案例

先看看xml

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="@dimen/px449" android:layout_height="@dimen/px323" android:orientation="vertical"> <LinearLayout android:id="@+id/root_layout" android:layout_width="@dimen/px400" android:layout_height="@dimen/px286" android:layout_centerInParent="true" android:background="@drawable/shape_rect_grid_item_bg" android:orientation="vertical" android:padding="@dimen/px4"> </LinearLayout> <View android:id="@+id/grid_border" android:layout_width="@dimen/px449" android:layout_height="@dimen/px322" android:layout_centerInParent="true" android:background="@drawable/border_bg" android:focusable="false" android:visibility="invisible"/> </RelativeLayout>

然后就是在选中中放大效果

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
gridView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { if (isGridFoucse && view != null) { if (mOldView != null) { LiveGridAdapter.ViewHolder oldholder = (LiveGridAdapter.ViewHolder) mOldView.getTag(); setGridBg(oldholder,false); } if (view != null) { LiveGridAdapter.ViewHolder holder = (LiveGridAdapter.ViewHolder) view.getTag(); view.bringToFront(); setGridBg(holder, true); } mOldView = view; curposition = position; } } @Override public void onNothingSelected(AdapterView<?> parent) { } }); private void setGridBg(final LiveGridAdapter.ViewHolder oldholder,boolean toBig){ if(toBig){ oldholder.root_layout.animate().scaleX(1.09f).scaleY(1.09f).setDuration(DEFAULT_TRAN_DUR_ANIM) .setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { if (oldholder.grid_border != null) { oldholder.grid_border.setVisibility(View.VISIBLE); } } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); }else{ oldholder.root_layout.animate().scaleX(1.0f).scaleY(1.0f).setDuration(DEFAULT_TRAN_DUR_ANIM) .setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { if (oldholder.grid_border != null) { oldholder.grid_border.setVisibility(View.INVISIBLE); } } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); } }

其实网上还有很多自定义Gridview 的放大效果,大家可以去搜索下看看



     

最后

以上就是心灵美机器猫最近收集整理的关于Android TV开发经验总结---控件Gridview使用的全部内容,更多相关Android内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(85)

评论列表共有 0 条评论

立即
投稿
返回
顶部