针对Android Tv的自定义RecyclerView2.0横竖向连动

版权声明:本文为博主原创文章,转载请注明出处。

推荐:
欢迎关注我创建的Android TV 专题,会定期给大家分享一些AndroidTv相关的内容:
http://www.jianshu.com/c/37efc6e9799b


前言:在上一篇针对Android Tv的自定义RecyclerView文章中介绍了横向的RecyclerView一些用法和实现方法。在上一篇的基础上,来实现RecyclerView横向和纵向的连动效果。

首先上效果图:

ezgif.com-gif-maker.gif

新的版本在上一个版本的基础上添加了一些内容以及读者反馈的bug.具体添加的内容如下:
1.添加了垂直的RecyclerView,并实现了可以控制横向recyclerView的效果。
2.左右箭头点击后RecyclerView的条目不会获得焦点,解决了滑动冲突。
3.横向RecyclerView5.0以下版本之后条目放上之后会出现被压盖的情况,这里修复了该bug。
4.在RecyclerView内部不再提供类似于放大抬高z轴的操作,这里只提供了focus状态的接口,具体的逻辑在RecyclerView使用处提供回调。

实现

下面具体来分析一下。
1.这里竖直的RecyclerView是在popupWindow中展示的。

  View popupView = getLayoutInflater().inflate(R.layout.list_menu_popwindow, null, false);
  mPopRecyclerView = (CustomRecyclerView)  popupView.findViewById(R.id.recycler_view);
  mUpArr = (ImageButton) popupView.findViewById(R.id.up_arrow);
  mDownArr = (ImageButton) popupView.findViewById(R.id.down_arrow);
  mPopupWindow = new PopupWindow(popupView, 404, 1920);
  mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#F8F8F8")));
  mPopupWindow.setFocusable(true);
  mPopupWindow.setOutsideTouchable(true);
  mPopupWindow.update();

注意:popupWindow要设置背景。
在popupWindow进入的时候我添加了一个进入的动画:

  mPopRecyclerView.setLayoutAnimation(PopLayoutAnimation.orderAnimation());

PopLayoutAnimation相关代码如下:

public class PopLayoutAnimation {
    private static Animation transAnim, alphaAnim;
    static LayoutAnimationController controller;

    public static LayoutAnimationController orderAnimation() {
        LayoutAnimationController controller;
        Animation transAnim, alphaAnim;
        AnimationSet set = new AnimationSet(false);
        transAnim = new TranslateAnimation(0, 0, -50, 0);
        transAnim.setDuration(167);
        transAnim.setFillEnabled(true);
        transAnim.setFillAfter(true);

        alphaAnim = new AlphaAnimation(0, 1);
        alphaAnim.setDuration(167);
        alphaAnim.setFillAfter(true);
        set.addAnimation(transAnim);
        set.addAnimation(alphaAnim);
        controller = new LayoutAnimationController(set, 1);
        controller.setDelay(0.33f);
        return controller;
    }

    public static LayoutAnimationController reserverAnimation(){
        AnimationSet set = new AnimationSet(false);
        transAnim = new TranslateAnimation(0, 0,50, 0);
        transAnim.setDuration(167);
        transAnim.setFillEnabled(true);
        transAnim.setFillAfter(true);
        // transAnim.setFillBefore(true);
        alphaAnim = new AlphaAnimation(0,1);
        alphaAnim.setDuration(167);
        alphaAnim.setFillAfter(true);
        set.addAnimation(transAnim);
        set.addAnimation(alphaAnim);
        controller = new LayoutAnimationController(set, 1);
        controller.setDelay(0.33f);
         controller.setOrder(LayoutAnimationController.ORDER_REVERSE);
        return controller;
    }
    public static boolean isNullAnimation(){
        if (controller==null||controller.isDone()){
            return true;
        }
        else{
            return false;
        }
    }
    public static void resetAnimation(){
        controller.start();
    }
}

2.横向的RecyclerView在使用的过程中发现在滚动的时候,鼠标放到Item上RecyclerView为了响应item获取焦点事件会停止滚动,达不到翻页的效果。这里处理了item响应时机。在RecyclerView处于idle状态时去响应。

 holder.itemView.setOnHoverListener(new View.OnHoverListener() {
                @Override
                public boolean onHover(View v, MotionEvent event) {
                    int what = event.getAction();
                    switch (what) {
                        case MotionEvent.ACTION_HOVER_ENTER:
                            RecyclerView recyclerView = (RecyclerView) holder.itemView.getParent();
                            int[] location = new int[2];
                            recyclerView.getLocationOnScreen(location);
                            int x = location[0];
//                            LogUtil.i("swj","GalleryAdapter.onHover.x="+x +",width = "+(recyclerView.getWidth()+x));
                            //为了防止滚动冲突,在滚动时候,获取焦点为了显示全,会回滚,这样会导致滚动停止
                            if (recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
                                //当超出RecyclerView的边缘时不去响应滚动
                                if (event.getRawX() > recyclerView.getWidth() + x || event.getRawX() < x) {
                                    return true;
                                }
                                //鼠标进入view,争取到焦点
                                v.requestFocusFromTouch();
                                v.requestFocus();
//                                LogUtil.i(this,"HomeTvAdapter.onHover.position:"+position);
                                focusStatus(v, position);
                            }
                            break;
                        case MotionEvent.ACTION_HOVER_MOVE:  //鼠标在view上移动
                            break;
                        case MotionEvent.ACTION_HOVER_EXIT:  //鼠标离开view
                            normalStatus(v, position);
                            break;
                    }
                    return false;
                }
            });

3.横向RecyclerView在Android5.0以后的系统,item在hover态时是抬高z轴,5.0以下版本之后条目放上之后会出现被压盖的情况,这里调整了一下布局。达到了兼容。

结束:

这里的RecyclerView用法和普通的RecyclerView用法类似,至于布局的显示,可以根据自己的项目去定义。
项目的地址:https://github.com/songwenju/CustomTvRecyclerView
如果对你有帮助,欢迎star和fork。如有问题,欢迎反馈交流。


推荐:
欢迎关注我创建的Android TV 专题,会定期给大家分享一些AndroidTv相关的内容:
http://www.jianshu.com/c/37efc6e9799b

版权声明:本文为博主原创文章,转载请注明出处。

你可能感兴趣的:(针对Android Tv的自定义RecyclerView2.0横竖向连动)