基于TVGridView的效果优化

前端时间在做安卓盒子的界面开发,网上搜索就看到了一个框架,很全面,但用DEMO看了下效果,只支持键盘的上下左右操作,不支持鼠标等的操作,但感觉做的还是可以的,就基于此类进行了优化,主要优化了以下几点:
1.加入支持鼠标的操作
2.加入滑动的效果
3.优化了界面的焦点效果及切换的过渡动画。
详细如下:
1.加入支持鼠标的操作
这个主要是在找到每个子view时,对每个子view增加一个设置即可,如下:

private void bindEventOnChild(View child, final int index) { //绑定事件
child.setFocusable(true);
child.setFocusableInTouchMode(true); //加入鼠标触摸的支持
。。。

2.加入滑动的效果
这部分主要是在TVGridView的外围,增加一个Scrollview控件,使其支持鼠标的拖动与滑动,但此时需修改onMeasure()方法,否则会出现bug
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.d(TAG, “onMeasure(int widthMeasureSpec, int heightMeasureSpec)”);
/**
* 获得此ViewGroup父容器为其推荐的宽和高,以及计算模式
*/
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);

//  Log.d(TAG, "sizeWidth="+sizeWidth+"sizeHeight="+sizeHeight);

    // 计算出所有的childView的宽和高
    measureChildren(widthMeasureSpec, heightMeasureSpec);

    int cCount = getChildCount();  //40
    Log.d(TAG, "cCount="+cCount);

    /**
     * 根据childView计算的出的宽和高,以及设置的margin计算容器的宽和高,主要用于容器是warp_content时
     */

    //wrap_content

    setMeasuredDimension(sizeWidth, rowHeight*rowCount+70 );  

}

3.优化了界面的焦点效果及切换的过渡动画。
这部分主要是对焦点的效果及过渡进行了重新处理,对于焦点更换了另外一种效果图,对于过渡的动画这部分,主要是增加焦点切换时,当前focus与下一个direction的焦点进行处理,
主要思路是,判断当前按下的是哪个方向健,根据此 得出focus与next的子view,如果next不为null,说明有下一个子view,则根据direction进行判断,对next子view进行做动画处理,如果next为null,说明已到边界,则也可以根据direction判断 分别作出靠边的动画效果,
部分代码如下:
public boolean dispatchKeyEventPreIme(KeyEvent event) {
Log.d(TAG, “dispatchKeyEventPreIme(KeyEvent event)”);
if (event.getAction() == KeyEvent.ACTION_DOWN) {

        if (!mScroller.isFinished()) {
            return true;
        }
        int direction = 0;
        switch (event.getKeyCode()) {
        case KeyEvent.KEYCODE_DPAD_DOWN:
            direction = View.FOCUS_DOWN;
            break;
        case KeyEvent.KEYCODE_DPAD_RIGHT:
            direction = View.FOCUS_RIGHT;
            break;
        case KeyEvent.KEYCODE_DPAD_UP:
            direction = View.FOCUS_UP;
            break;
        case KeyEvent.KEYCODE_DPAD_LEFT:
            direction = View.FOCUS_LEFT;
            break;  
        }

        View focused = this.findFocus(); //当前有焦点的item
        if (focused != null && direction != 0) {

            View next = focused.focusSearch(direction);//根据方向确定的下一个view                     
            // 根据下标算出所在行
            if (next != null) {                         
                int focusIndex = itemIds.get(focused.getId());          
                Integer temp = itemIds.get(next.getId());
                int nextRow = 0;                    

                // 焦点切出容器时
                if (temp != null) {  //next不为null 对direction的view做动画
                    focusIsOut=false;
                    selectIndex = temp; 
                    if(direction == View.FOCUS_DOWN) {
                        enScrollDown=true;                  
                        AnimationViewDown(next);                            
                    }else if(direction == View.FOCUS_LEFT) {    
                        onetimes=false; //去除按左键时 scrollview向上移动的bug
                        AnimationViewLeft(next);
                    }else if(direction == View.FOCUS_RIGHT) {
                        onetimes=false;//去除按右键时 scrollview向上移动的bug
                        AnimationViewRight(next);
                    }else if(direction == View.FOCUS_UP) {
                        enScrollUp=true;        
                        AnimationViewUp(next);
                    }

                    selectRow = focusIndex / columns;
                    nextRow = selectIndex / columns;

                    Log.d(TAG, "selectRow="+selectRow+"nextRow="+nextRow);
                    if(nextRow==1) { //第2行
                    //  onetimes=true;
                    }

                } else {
                    Log.d(TAG, "焦点切出容器");
                    parentLayout = true;
                    focusIsOut=true;    
                    firstFocus=true; //保证每次再切入焦点时 第一行的app 有动画
                    return super.dispatchKeyEventPreIme(event);
                }



            }else { //已到边源,next会为null,对当前的view动画

                if(direction == View.FOCUS_DOWN) {
                    AnimationViewDown(focused);                         
                }else if(direction == View.FOCUS_LEFT) {
                    AnimationViewLeft(focused);
                }else if(direction == View.FOCUS_RIGHT) {
                    AnimationViewRight(focused);
                }else if(direction == View.FOCUS_UP) {
                    AnimationViewUp(focused);
                }

            }

        }   

    }

    return super.dispatchKeyEventPreIme(event);
}

动画实例:
private void AnimationViewDown(View item) { //向下
ObjectAnimator mAnimatorTranslateY = ObjectAnimator.ofFloat(item, “translationY”, 0.0f,10f,0f);
mAnimatorTranslateY.setRepeatMode(Animation.REVERSE);
// mAnimatorTranslateY.setRepeatCount(3);
mAnimatorTranslateY.setInterpolator(new DecelerateInterpolator());
mAnimatorTranslateY.setDuration(1000);
mAnimatorTranslateY.start();

}

焦点效果如下:
焦点效果图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值