安卓gridview控件的使用

本文探讨了在Android TV开发中使用GridView时遇到的焦点混乱和性能问题,并推荐了Android-TV-Frame框架中的GridViewTV控件。文章详细介绍了如何处理GridView的选中、点击、焦点变化事件,以及如何避免初始化时自动选中第一个Item。此外,还分享了实现Item放大的动画效果和分页加载数据的策略。
摘要由CSDN通过智能技术生成

安卓gridview控件的使用

前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? ? ?选中事件.

    //选中事件

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){

}

});

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

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

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

接着说说我们在GridView开发中需要判断是否焦点在Item边缘地带了可以使用如下方法做判断,仅供参考需要自己完善自己逻辑

/**

* 判断当前选中的位置在屏幕中的相对位置

*

* @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

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;

}

}

如果这时候你还需要通过方向来确定的话可以使用如下代码

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中然后暴露回调接口出来

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

switch (keyCode) {

case KeyEvent.KEYCODE_DPAD_DOWN:

if (isGridFoucse) { //

if (getGridSelectionState() == BOTTOM && isHaveMore) { //翻页

//TODO:加载数据

return true;

}

}

break;

}

return false;

}

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

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

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

先看看xml

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="@dimen/px449"

android:layout_height="@dimen/px323"

android:orientation="vertical">

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">

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"/>

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

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 的放大效果,大家可以去搜索下看看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫叶思念

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值