一步一步学习Android TV/盒子开发(三)

本文主要说的就是在TV开发中常遇到的问题总结

焦点丢失问题

在使用ListView、GridView及RecyclerView时有时会出现,这时需要在xml中,添加

android:descendantFocusability="afterDescendants"

这里会有三种方式分别为

  • beforeDescendants:viewgroup会优先其子类控件而获取到焦点

  • afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点

  • blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点

在使用自定义组合控件是可以用代码设置,如下

setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS);

控件调用bringToFront失效,导致焦点错乱问题

源码中:

  • View

      public void bringToFront() {
          if (mParent != null) {
              mParent.bringChildToFront(this); // 是调用父布局的 bringChildToFront
          }
      }
    
  • ViewGroup

      @Override
      public void bringChildToFront(View child) {
          final int index = indexOfChild(child);
          if (index >= 0) {
              removeFromArray(index); // 删除子控件数组位置.
              addInArray(child, mChildrenCount); // 添加子控件到队尾.
              child.mParent = this;
              requestLayout();
              invalidate();
          }
      }
    
  • 所以可以将你要置顶的子控件和最后一个要绘制的控件交换位置, 因为最后绘制的子控件是在最上面的。

      setChildrenDrawingOrderEnabled(true)
    
      @Override
      protected int getChildDrawingOrder(int childCount, int i) {
          if (position != -1) {
              if (i == childCount - 1)
              return position;
          if (i == position) 
              return childCount - 1;
          }
          return i;
      }
    
  • ViewUtil

      public class ViewUtil {
          private final ViewGroup viewGroup;
          private int position;
      
          public ViewUtil(ViewGroup group) {
              this.viewGroup = group;
          }
      
          public void bringChildToFront(ViewGroup vg, View child) {
              position = vg.indexOfChild(child);
              if (position != -1) {
                  vg.postInvalidate();
              }
          }
      
          public void bringChildToFront(View child) {
              if (viewGroup == null) {
                  return;
              }
              position = viewGroup.indexOfChild(child);
              if (position != -1) {
                  viewGroup.postInvalidate();
              }
          }
      
          public int getChildDrawingOrder(int childCount, int i) {
              if (position != -1) {
                  if (i == childCount - 1)
                      return position;
                  if (i == position)
                      return childCount - 1;
              }
              return i;
          }
      }
    
  • 在Android5.0以后可以通设置控件的Z坐标达到相同的效果

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
          ViewCompat.setElevation(view, 1);
      } else {
          if (view.getParent() instanceof BringChildLinearLayout) {
              BringChildLinearLayout layout = (BringChildLinearLayout) view.getParent();
              layout.bringChildToFront(view);
          }
      }
    

跑马灯失效

  • 自定义TextView实现跑马灯时,设置单行时用“maxLines=1”不生效,应该使用“singleLine=true”(过期的API)。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容