二、TV上RecyclerView移动焦点放大实现

2022-12-09  本文已影响0人  aitality

在电视上主要的交互就是使用遥控器控制焦点进行选择,所以一个醒目的选中效果会带来很好的体验度。目前上面上的焦点框有两种,第一种是飞框,第二种就是selector,其中飞框的体验是最好的,看着焦点框在屏幕上划过,像流星一样很美,但是实现成本也很高。这里我还是使用常规selector方式实现。简单说一下飞框的实现原理:就是全局监听当前获得焦点的viewgetViewTreeObserver().addOnGlobalFocusChangeListener(),然后将最上层的焦点框以到焦点位置,并添加放大效果。

第一步、编写selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/general_focus" android:state_focused="true" />
    <item android:drawable="@drawable/item_grid_state_normal" />
</selector>

第二步、监听RecyclerView.ViewHolderitemView的焦点变化

holder.itemView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if(hasFocus) {
                    focusedTo(v);
                }else{
                    focusedFrom(v);
                }
            }
        });

第三步、实现选中和非选中动画

public void focusedTo(View view) {
        ViewCompat.animate(view).scaleX(1.2f).scaleY(1.2f).translationZ(1.2f).start();
}

public void focusedFrom(View view) {
        ViewCompat.animate(view).scaleX(1.0f).scaleY(1.0f).translationZ(0f).start();
}

第四步、优化RecyclerView显示顺序,放置放大item被遮挡

//继承RecyclerView实现
//防止item放大后被遮挡
protected int getChildDrawingOrder(int childCount, int i) {
      int position = getChildAdapterPosition(getFocusedChild());
      if(position < 0) {
         return i;
      }
      if(i == childCount-1) {
         if(position > i) {
            position = i;
         }
         return position;
      }
      if(i == position) {
         return childCount-1;
      }
      return i;
   }

以下代码可避免边缘的item被裁剪

android:clipChildren="false"
android:clipToPadding="false"
上一篇下一篇

猜你喜欢

热点阅读