This article is from NetEase Cloud community

Author: Sun Youjun


Problem 3: There is no entry icon in the TV Launcher

If need entry icon appears, you must configure the action in the AndroidManifest for android. The intent. The action. The MAIN, the category for android. The intent. The category. The LAUNCHER Activity. This configuration does not conflict with the above LEANBACK_LAUNCHER. You can configure the LAUNCHER for the entry Activity, and configure the LEANBACK_LAUNCHER for the next page as follows:

<activity
    android:name=".WelcomeActivity"
    android:label="@string/app_name"
    android:screenOrientation="landscape">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>

        <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
    </intent-filter></activity>Copy the code


Problem 4: ICONS in TV Launcher are not clear and are too vague

If the icon of the mobile app launcher is directly used in a TV, the icon will be stretched. Since the icon of the TV is usually large, it will become paste after stretching, so we need to cut the icon of the launcher. The ICONS in the phone are 4848, 7272,9696, etc., while the TV needs a larger size. Although I did not find the recommended size in the official, I recommend a size of 180180. Multiple folders can put the same icon, so that the icon loaded on the interface will become clear.



Problem 5: Remote control navigation next control that you do not want to navigate

In the system, if there are multiple focus controls in the interface, navigate up, down, left and right, and you will find the control closest to the current control as the next selected control. Therefore, if you want to specify the next navigation control, you can specify the ID of the next control, as long as the ID is in the current display interface. For example, go up view1.setNextfocusupId (R.i.D.dial_tab);


Problem 6: After the official VerticalGridFragment is loaded, the first one is selected by default, but the first one occupies the entire interface.

This problem should be an official bug, if it is not the first time to load VerticalGridFragment, this problem will not occur, and I have tried several versions of the problem, the reason is that the system will insert two frames of NonOverlappingView after the selected control, Insert the following layout code:


<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <android.support.v17.leanback.widget.NonOverlappingView      
      android:id="@+id/lb_shadow_normal"       
       android:layout_width="match_parent"      
         android:layout_height="match_parent"      
           android:background="@drawable/lb_card_shadow_normal" />
    <android.support.v17.leanback.widget.NonOverlappingView      
      android:id="@+id/lb_shadow_focused"      
        android:layout_width="match_parent"        
        android:layout_height="match_parent"        
        android:background="@drawable/lb_card_shadow_focused"     
           android:alpha="0" />

</merge>Copy the code

The layout is overlapted with two frames of NonOverlappingView, each frame with a.9 icon as the background, and when the system is first loaded, finally the first selected control width and height calculation error, calculated to a similar value of 16777211, far beyond the size of the interface, the solution is as follows:

Solution 1, change match_parent to WRap_content solution 2, set ShadowEnabled for VerticalGridPresenter used in VerticalGridFragment. Such as gridPresenter. SetShadowEnabled (false); Plan 3, replace the.9 picture


Fault 7: After the VerticalGridFragment is loaded, the zoom effect is not centered

In a VerticalGridFragment, if the ArrayObjectAdapter uses a Presenter that it implements and the Presenter uses an ImageCardView that is not provided by the system, the selection is not centered. When selected, the effect will zoom down to the right instead of around the current position.

I have checked the corresponding style, only for ImageCardView style, I have not studied how to adjust, but here is a solution to avoid, VerticalGridPresenter after the highlight set to no magnification, Such as new VerticalGridPresenter (FocusHighlight ZOOM_FACTOR_NONE).


Problem 8: The VerticalGridFragment top-level control cannot navigate upwards

For example, in the first line of the contact list page, the remote control can not navigate up, such as the dial-up, friends control, this problem is actually blocked by the system. The system’s VerticalGridFragment loads the lb_vertical_grid_fragment layout, which contains a BrowseFrameLayout, SetOnFocusSearchListener is set for BrowseFrameLayout. As follows:

   private void setupFocusSearchListener() {
        BrowseFrameLayout browseFrameLayout = (BrowseFrameLayout) getView().findViewById(
                R.id.grid_frame);
        browseFrameLayout.setOnFocusSearchListener(getTitleHelper().getOnFocusSearchListener());
    }Copy the code

When the system is at the top of the VerticalGridPresenter, it looks up the nearest control and finds that there are no controls in the current layout, so it looks up the parent layout as follows:

public View focusSearch(View focused, int direction) {   
 if (isRootNamespace()) {        
 // root namespace means we should consider ourselves the top of the
        // tree for focus searching; otherwise we could be focus searching
        // into other tabs.  see LocalActivityManager and TabHost for more info
        return FocusFinder.getInstance().findNextFocus(this, focused, direction);
    } else if(mParent ! = null) {return mParent.focusSearch(focused, direction);
    }    return null;
}Copy the code

And VerticalGridPresenter parent layout is BrowseFrameLayout, so eventually execution is set above getTitleHelper () getOnFocusSearchListener (), we look at the listener instead:

private final BrowseFrameLayout.OnFocusSearchListener mOnFocusSearchListener =      
      new BrowseFrameLayout.OnFocusSearchListener() {   
           @Override
        public View onFocusSearch(View focused, int direction) {      
              if(focused ! = mTitleView && direction == View.FOCUS_UP) {return mTitleView;
            }           
             final boolean isRtl = ViewCompat.getLayoutDirection(focused) ==
                    View.LAYOUT_DIRECTION_RTL;          
                      final int forward = isRtl ? View.FOCUS_LEFT : View.FOCUS_RIGHT;       
                           if (mTitleView.hasFocus() && direction == View.FOCUS_DOWN || direction == forward) {   
                                        return mSceneRoot;
            }        
                returnnull; }};Copy the code

Did you find the problem when Focused! When = mTitleView && direction == view. FOCUS_UP, mTitleView is forcibly specified, even if title is not displayed. I think this should be a bug in the system, how to solve it?

We could rewrite the same lb_vertical_grid_fragment, override the system’s layout, and rewrite BrowseFrameLayout as our own. The following

public class BrowseFrameLayout extends android.support.v17.leanback.widget.BrowseFrameLayout {    public BrowseFrameLayout(Context context) {        super(context);
    }    public BrowseFrameLayout(Context context, AttributeSet attrs) {        super(context, attrs);
    }    public BrowseFrameLayout(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);
    }    /**
     * Sets a {@link OnFocusSearchListener}.
     */
    public void setOnFocusSearchListener(OnFocusSearchListener listener) {

    }
}Copy the code


Problem 9: VerticalGridFragment content does not fill the entire screen

<! --BrowseFragment, RowsFragment, DetailsFragment padding Left distance </item>--> <item name="browsePaddingStart">@dimen/lb_browse_padding_start</item> <! --BrowseFragment, RowsFragment, DetailsFragment padding Right distance </item>--> <item name="browsePaddingEnd">@dimen/lb_browse_padding_end</item> <! </item>--> <item name="browsePaddingTop">@dimen/lb_browse_padding_top</item> <! </item>--> <item name="browsePaddingBottom">@dimen/lb_browse_padding_bottom</item> <! --start margin of RowsFragment inside BrowseFragment when HeadersFragment is visible</item>--> <item name="browseRowsMarginStart">@dimen/lb_browse_rows_margin_start</item> <! --top margin of RowsFragment inside BrowseFragment when BrowseFragment title is visible</item>--> <item name="browseRowsMarginTop">@dimen/lb_browse_rows_margin_top</item>Copy the code

If you are using a BrowseFragment, control the margin above. If you are using a VerticalGridFragment, overwrite itemsVerticalGridStyle, which also uses the values defined above. You can also set the values directly:

<style name="ItemsVerticalGridStyle" parent="@style/Widget.Leanback.GridItems.VerticalGridView">
    <item name="horizontalMargin">@dimen/gap_12_dp</item>
    <item name="verticalMargin">@dimen/gap_12_dp</item>

    <item name="android:focusable">true</item>
    <item name="android:focusableInTouchMode">true</item>
    <item name="android:paddingStart">? attr/browsePaddingStart</item> <item name="android:paddingEnd">? attr/browsePaddingEnd</item> <item name="android:paddingBottom">@dimen/lb_vertical_grid_padding_bottom</item>
    <item name="android:paddingTop">? attr/browseRowsMarginTop</item> <item name="android:gravity">center_horizontal</item>
    <item name="focusOutFront">true</item>
</style>Copy the code

Style adjustment

If you need to modify some of the VerticalGridFragment styles, you can redefine a Theme derived from Theme.Leanback. Here we outline some of the effects. You can control the margins around the content of the VerticalGridFragment, and you can control the visual effects of the ImageCardView.

<style name="AppTheme" parent="@style/Theme.Leanback"> <! --BrowseFragment, RowsFragment, DetailsFragment padding Left distance </item>--> <item name="browsePaddingStart">@dimen/lb_browse_padding_start</item> <! --BrowseFragment, RowsFragment, DetailsFragment padding Right distance </item>--> <item name="browsePaddingEnd">@dimen/lb_browse_padding_end</item> <! </item>--> <item name="browsePaddingTop">@dimen/lb_browse_padding_top</item> <! </item>--> <item name="browsePaddingBottom">@dimen/lb_browse_padding_bottom</item> <! --start margin of RowsFragment inside BrowseFragment when HeadersFragment is visible</item>--> <item name="browseRowsMarginStart">@dimen/lb_browse_rows_margin_start</item> <! --top margin of RowsFragment inside BrowseFragment when BrowseFragment title is visible</item>--> <item name="browseRowsMarginTop">@dimen/lb_browse_rows_margin_top</item> <! --fading edge length of start of browse row when HeadersFragment is visible</item>--> <item name="browseRowsFadingEdgeLength">@dimen/lb_browse_rows_fading_edge</item>

    <item name="baseCardViewStyle">@style/BaseCardViewStyle</item>

    <item name="overlayDimMaskColor">@color/transparent</item>
    <item name="overlayDimActiveLevel">@fraction/lb_view_active_level</item> <! </item>--> <item name="overlayDimDimmedLevel">0%</item>

    <item name="itemsVerticalGridStyle">@style/ItemsVerticalGridStyle</item>
</style>

<style name="BaseCardViewStyle" parent="@style/Widget.Leanback.BaseCardViewStyle">
    <item name="cardForeground">@color/transparent</item>
    <item name="cardBackground">@color/transparent</item>
</style>

<style name="ItemsVerticalGridStyle" parent="@style/Widget.Leanback.GridItems.VerticalGridView">
    <item name="horizontalMargin">@dimen/gap_12_dp</item>
    <item name="verticalMargin">@dimen/gap_12_dp</item>

    <item name="android:focusable">true</item>
    <item name="android:focusableInTouchMode">true</item>
    <item name="android:paddingStart">? attr/browsePaddingStart</item> <item name="android:paddingEnd">? attr/browsePaddingEnd</item> <item name="android:paddingBottom">@dimen/lb_vertical_grid_padding_bottom</item>
    <item name="android:paddingTop">? attr/browseRowsMarginTop</item> <item name="android:gravity">center_horizontal</item>
    <item name="focusOutFront">true</item>
</style>

<style name="ImageCardViewInfoAreaStyle" parent="@style/Widget.Leanback.ImageCardView.InfoAreaStyle">
    <item name="android:background">@null</item>
</style>

<style name="ImageCardViewStyle" parent="@style/Widget.Leanback.ImageCardViewStyle">
    <item name="cardBackground">@color/transparent</item>
</style>Copy the code


NetEase Cloud Free experience pavilion, 0 cost experience 20+ cloud products!


For more information about NetEase’s r&d, product and operation experience, please visit NetEase Cloud Community


Start SpringBoot (4) — automatic configuration