1, the preface

You should be familiar with using TabLayout and ViewPager components in mobile App development. However, the operation mode of mobile phone is different from that of TV with remote control. Can you directly use these components in TV development? What is the problem if it cannot be used directly?

I didn’t test using TabLayout and ViewPager directly in TV development, but after reading the source code, I guessed there might be some problems:

  • TabLayoutUse in the phone by clicking the Tab to trigger the response while inTVGoogle suggests it should be usedTabtheFocusChange to trigger a response
  • TabLayouttheitem viewShould not be able to get focus (eachTabIntrinsically correspondingViewIs aTabView.TabLayoutBased on the internalLinearLayoutRealized).
  • ViewPagerThe default page turn is based on the click of a button, as suggested in some Google documentation or codeViewPagerinTVIf withTabLayoutSyndication (or other navigational actions) should be prohibitedViewPagerScroll through the left and right keys (roughly this meaning, I post the original text later).

The above problems are not serious, and can be basically solved after simple modification. But my intuition tells me that there should be corresponding library support, otherwise TabLayout can only be used on Phone, which is too weak. Sure enough, after a bit of searching, the JitPack provides the leanback-Tab, but this is clearly not the focus of this article, but the custom leanback-Tab

2,leanback-tab

The library is officially provided to provide the linkage scenario of TV development using TabLayout+ViewPager. The code is not much, and the general functions are as follows:

2.1 LeanbackViewPager

Add the following to the ViewPager:

  • Enable/disableTouchEvent(Disabled by default)
  • Enable/disableKeyEvent(Disabled by default)

The code is very simple, you can see the source code to understand;

2.2 LeanbackTabLayout

The following content is added based on TabLayout

  • withViewPagerIn the case of linkage,TabthroughFocusChange the switchViewPager
  • Focus memory: i.eTabLayoutWhen getting focus vertically, the previously selected focus is preferredTabGet focus

Less than 2.2

Although the library is officially provided for support, it also allows TabLayout and ViewPager to be used together in TV development from a very basic level, but it does not mean that they can be used well and have rich functions. Some interactive scenes need to be optimized.

The following can be further optimized:

2.2.1 ViewPagerLook internally for the next focusViewWill be transferred toViewPagerIn addition to theViewon

In some cases, when the ViewPager responds to the left and right buttons of the remote, we want the focus to shift just inside the ViewPager.

2.2.2 TabLayoutLeft and right boundariesTabResponse to the focus seeking problem of horizontal remote control button direction

In some cases, when the TabLayout responds to the left and right buttons of the remote control, we want the focus to shift only within the TabLayout.

2.2.3 TabLayoutwithViewPagerWhen usedTabThe customViewThe problem of

This is a well-known problem (and also in mobile development) : We can customize the Tab with tabLayout.newTab().setCustomView(), but when we use the tabLayout setupWithViewPager method with ViewPager, TabLayout removes all existing tabs by default, and then creates tabs using ViewPager PagerAdapter#getPageTitle. You can also manually bind TabLayout to ViewPager without calling setupWithViewPager. LeanbackTabLayout is the viewPager associated with the setupWithViewPager method, which triggers the viewPager page turn in the Focus listener.

If with TabLayout dynamic refresh, Tab style dynamic changes, processing is still quite a head.

So these problems basically lead to TabLayout and ViewPager not being very convenient to use together;

3,bas-leanback-tab

This library combines bas-leanBack with more extensions to address general needs on TV.

3.1 LeanbackViewPager

3.1.1 Enabling/DisablingTouchEvent(Disabled by default)

Corresponding XML attribute: app:touchEnabled_lbt

fun setTouchEnabled(enableTouch: Boolean)
Copy the code

3.1.2 Enabling/Disabling the FunctionKeyEvent(Disabled by default)

Corresponding XML attribute: app:keyEventEnabled_lbt

fun setKeyEventsEnabled(enableKeyEvent: Boolean)
Copy the code

3.1.3 Setting whether boundary focus is moved out (default not allowed)

Corresponding XML attribute: app:focusOutEnabled_lbt

/** * Optimize border focus rules: whether the focus in [ViewPager] is allowed to shift outside [ViewPager] when the left and right buttons are triggered */ fun setFocusOutEnabled(enableFocusOut: Boolean) { focusOutEnabled = enableFocusOut }Copy the code

3.2 LeanbackTabLayout

LeanbackTabLayout is based on TabLayout extension, so TabLayout itself supports basically all functions are supported, such as setting fixed TAB or scroll TAB, setting TAB selected indicator (bar below TAB), etc.

3.2.1 TVOperational support

Corresponding XML attribute: app:isLeanbackMode_lbt When running on TV, trigger Tab selection event by Tab Focus (Tab click on mobile phone)

fun setLeanbackMode(isLeanback: Boolean)
Copy the code

The TV operation is supported by default, because even if the TV operation is enabled, it does not affect the operation on the phone.

Note: The library’s focus event bindings are straightforward.

3.2.2 Optimization of boundary focusing rules

Corresponding XML attribute: app:focusOutEnabled_lbt

/** * Optimize border focus rules: when the left and right buttons of the remote control are triggered, whether the focus in [TabLayout] can be shifted outside [TabLayout] */ fun setFocusOutEnabled(enableFocusOut: Boolean) { focusOutEnabled = enableFocusOut }Copy the code

3.2.3 Focus memory

The corresponding XML attribute is as follows: app:focusMemoryEnabled_lbt TabLayout When you obtain the focus, the previously selected TAB obtains the focus first

fun setFocusMemoryEnabled(enableFocusMemory: Boolean)
Copy the code

3.2.4 ViewPagerLinkage usage scenarios and customizationTabProcessing etc.

Support for the system’s setupWithViewPager method

fun setupWithViewPager(viewPager: ViewPager? , autoRefresh:Boolean)
Copy the code

Support for custom Tab styles in conjunction with ViewPager, making it easy to use text, text ICONS, custom Tab usage scenarios, and even a complete mix of styles.

/** * Initialize according to ViewPager; *@paramTabConfigurationStrategy TAB configuration strategy for customizing TAB styles. * [TabConfigurationStrategy TextStrategy] : text * TAB strategy TabLayout [TabConfigurationStrategy ViewPagerStrategy] : [system in conjunction with the ViewPager rules) Use the ViewPager adapter getPageTitle method to create the Tab text strategy * [TabConfigurationStrategy. TextIconStrategy] : * text + icon strategy [TabConfigurationStrategy. CustomViewStrategy] : Custom view strategy, [TabConfigurationStrategy CustomViewFactory] * if the above strategies cannot meet the demand, can customize the implementation [TabConfigurationStrategy]. *@paramAutoRefresh [viewpager. getAdapter] Whether to refresh Tab */ automatically when data changes
fun setupWithViewPager(
    viewPager: ViewPager? , tabConfigurationStrategy:TabConfigurationStrategy,
    autoRefresh: Boolean = true
) 
Copy the code

3.2.5 Refreshing Adapter and Tab

Whenever the ViewPager changes the Adapter or calls the notifyDataSetChanged method of the Adapter to notify the refresh of the update, the TabLayout will synchronize the update.

3.2.6 Other instructions

TabLayout fully encapsulated with the linkage of the ViewPager to LeanbackTabLayoutMediator class, the class can also be used alone.

3.3 the use of

The library is very simple to use, check LeanbackTabLayout setupWithViewPager method can be understood; In addition, the supported functions have been listed in front of the corresponding API and attribute, call Settings at any time.

// The simplest way to use it: Tab will display method according to the Adapter getPageTitle text Tab effect binding. TabLayout. SetupWithViewPager (binding. TabViewPager) / / custom Tab allocation strategy way of use: Library built-in several strategies, ViewPagerStrategy corresponding to the system processing, that is, the use of the above is the same, Other strategies see TabConfigurationStrategy binding. TabLayout. SetupWithViewPager ( binding.tabViewPager,TabConfigurationStrategy.ViewPagerStrategy(binding.tabViewPager) )Copy the code

3.4 Rough Demo Screenshot

Finally, paste the Github address of this library