美文网首页Android TV开发
一步一步学习Android TV/盒子开发(三)

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

作者: AFatty | 来源:发表于2017-03-24 15:27 被阅读796次

    本文主要说的就是在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)。

    相关文章

      网友评论

        本文标题:一步一步学习Android TV/盒子开发(三)

        本文链接:https://www.haomeiwen.com/subject/wmdfottx.html