Step by step learning Android TV / box development (3)

Posted by gite_ashish on Fri, 03 Jan 2020 12:03:30 +0100

This paper mainly talks about the summary of the problems often encountered in the development of TV

Focus loss issues

Sometimes when using ListView, GridView and RecyclerView, you need to add

android:descendantFocusability="afterDescendants"
  • 1
  • 2

There are three ways to do this

  • beforeDescendants: viewgroup takes precedence over its subclass controls to get focus

  • afterDescendants: viewgroup gets focus only when its subclass control does not need to get focus

  • Blocksdedendants: viewgroup will override the subclass control and get the focus directly

In the use of custom composite control, you can use code settings, as follows

setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS);
  • 1
  • 2

Control call bringToFront failed, leading to focus confusion

Source code:

  • View

    public void bringToFront() {
        if (mParent != null) {
            mParent.bringChildToFront(this); // Is the bringchildtofofront that calls the parent layout
        }
    }
    
  • ViewGroup

  • So you can exchange the position of the sub control you want to top with the last control you want to draw, because the last sub control you want to draw is on the top.

    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;
        }
    }
    
  • After Android 5.0, you can achieve the same effect by setting the Z coordinate of the control

    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);
        }
    }
    

Running lamp failure

  • "maxLines=1" does not work when setting a single line, and "singleLine=true" (expired API) should be used.

Topics: Android