Recently, I was doing TV development based on Android. At the beginning, I was afraid of losing. I had never touched this before. Big guy said not to panic, and mobile phone development is basically the same……

I read some articles and found that they are basically the same. The biggest difference is the way they interact with users. Mobile phones give feedback by tapping the touch screen, while TVS give feedback by tapping the remote control.

The biggest difference between TV development and mobile development is that it responds to the button click of remote control and handles the focus jump of View.

At present, domestic TV development environment is to create an Android project, rather than an Android TV project. It can be considered that the DOMESTIC TV APP is a horizontal version of the APP with a long screen, plus some focus issues only……

Let’s take a closer look at the differences between TV development and mobile development:

1, connect

TV development, unlike mobile development, is debugged via a USB cable connection. You can find the TV’s IP address in the TV’s network Settings and connect with the following ADB command. Once connected, you can operate the TV device in AS.

// Adb connect 170.2.10.20 // Disconnect adb Disconnect 170.2.10.20Copy the code

Because my TV system is also the development version of the system, so it can be directly connected. If you can’t connect, you might want to turn on the TV’s developer option license…..

2. Keyboard input

Compared with the input method of mobile phone, it can be said that it is much more complicated. TV is not touch screen, each character need to operate the remote control, through up and down to find the character, click confirm input.

It’s a nightmare to go back and delete an earlier character if you find it wrong.

Some remote controls already have infrared operating devices, and the input characters are similar to mouse clicking on the keyboard, but it is still complicated compared with the touch screen of mobile phones…….

You can quickly enter a string into the TV’s input box with the following ADB command

adb shell input text "hello,world"
Copy the code

Mother no longer worried that I have no patience to hit the TV…..

3. Focus control

The button state of the TV is a little more complicated than that of the phone.

Mobile APP users can click anywhere, there is no limit. Click on the event, no click on the event, all want to dot try.

For TV users, you need to limit which part the user can click and which part can’t, so you need to use the remote control to jump up and down left and right to limit the View or focus. And need to tell the user at all times the current focus of what position, convenient for the next operation.

1. Set available focus

In the layout file

android:focusable="true"
Copy the code

In the code

view.setFocusable(true);
Copy the code

2. Set touch to get focus

In the layout file

 android:focusableInTouchMode="true"
Copy the code

In the code

view.setFocusableInTouchMode(true);
Copy the code

2, View focus monitor

view.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, Boolean hasFocus) {if (hasFocus) {elseif (hasFocus) {elseif (hasFocus) {elseif (hasFocus) {elseif (hasFocus) {elseif (hasFocus);Copy the code

3, When the View gets the focus, set the next View to get the focus

In the layout file:

 android:nextFocusDown="@id/button1"
 android:nextFocusUp="@id/button2"
 android:nextFocusLeft="@id/button3"
 android:nextFocusRight="@id/button4"
Copy the code

In the code:

 view.setNextFocusDownId(R.id.button1);
 view.setNextFocusUpId(R.id.button2);
 view.setNextFocusLeftId(R.id.button3);
 view.setNextFocusRightId(R.id.button4);

Copy the code

4. Determine the position of focus

One of the biggest headaches in TV development is that when you press the remote control, you don’t know where the focus is. It is clear that all views limit the ability to obtain focus, and the state of obtaining focus. It’s still going to show up and when you hold it down you don’t know where the focus goes. This can easily occur in complex custom views.

This time will phase method positioning to the focus to hide where to……

ViewTreeObserver observer = getWindow().getDecorView().getViewTreeObserver(); observer.addOnGlobalFocusChangeListener(new ViewTreeObserver.OnGlobalFocusChangeListener() { @Override public void onGlobalFocusChanged(View oldFocus, View newFocus) { VLog.d(TAG, "oldFocus: " + oldFocus + "/n" + "newFocus: " + newFocus); }});Copy the code

Set the Window’s global focus listener to print out views that lose focus and those that gain focus.

5. Button monitoring

The UI may want to animate a View’s press, so listen for the remote control’s press and animate it.

How do you listen in on that?

view.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { // In this case, when the remote control return key is pressed, return true; } return false; }});Copy the code

Commonly used remote control keys:

KEYCODE_DPAD_DOWN // keyevent.keycode_dpad_up // up keyevent.keycode_dpad_left KEYCODE_DPAD_RIGHT // right-click keyevent. KEYCODE_MENU // keyevent. KEYCODE_SETTINGS // Set keyCopy the code

As with mobile development, the HOME button doesn’t listen

DescendantFocusability attribute

In a complex custom View, only the outer parent View can get focus, and the child View can’t get focus anyway. How do I get a child View to get focus? DescendantFocusability property helps

The official definition looks like this:

<! -- Defines the relationship between the ViewGroup and its descendants when looking for a View to take focus. --> <attr name="descendantFocusability"> <! -- The ViewGroup will get focus before any of its descendants. --> <enum name="beforeDescendants" value="0" /> <! -- The ViewGroup will get focus only if none of its descendants want it. --> <enum name="afterDescendants" value="1" /> <! -- The ViewGroup will block its descendants from receiving focus. --> <enum name="blocksDescendants" value="2" /> </attr>Copy the code

DescendantFocusability is an attribute of View. Use this property to specify which viewGroup or its subviews gets focus, directly on the layout of the viewGroup’s XML.

android:descendantFocusability="afterDescendants"
Copy the code

The values of the three attributes are:

  • BeforeDescendants: A viewGroup takes precedence over its subclass controls to get focus
  • AfterDescendants: A viewGroup gets focus only when its subclass controls do not need it
  • BlocksDescendants: viewGroup overrides subclass controls to get focus directly

5. UI state

In order to facilitate the operation of users, better prompt users. Button has focus state, press state, click state and other states, these possibilities need to be dealt with. Something like this

This one is actually relatively easy to solve with a SelectDrawable

<? The XML version = "1.0" encoding = "utf-8"? > <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/bg_focus" android:state_focused="true" /> <item android:drawable="@drawable/bg_press" android:state_pressed="true" /> <item android:drawable="@drawable/bg_select" android:state_selected="true" /> <item android:drawable="@drawable/bg_normal" /> </selector>Copy the code

6. Simulator simulates TV resolution

UI development can also be a challenge if the TV screen is particularly large. Today’s TVS tend to start at more than 50 inches, which is too big. You have to step back from the TV to see a UI effect. Who can stand such development? This time you need the simulator to help you, with the simulator to simulate the RESOLUTION of the TV, you can directly see the effect on the local simulator. No longer three or five meters away from the TV……

The MuMu emulator I used to set the resolution should also be supported by other third-party emulators

7. Chrome plugin simulates remote click

Since we’re using simulators to simulate TV, there’s one thing missing. The PC emulator, while not touch, requires a mouse to operate. It’s different from the TV remote control.

Is there a tool that operates the simulator like a remote control to simulate up, down, left, right buttons? The answer is yes.

Chrome plugin, ChromeADB can simulate the operation of a remote control on your device

Download address: chrome.google.com/webstore/de…

If you can’t surf the Internet scientifically, you can go to GitHub to download and install it offline: github.com/importre/ch…

When the installation is complete, connect the emulator. The Keyboard on the right can be used as a remote control to operate devices.

8, the RecyclerView focus of the RecyclerView

In the development of Android TV application, remote control is used to control the focus of RecyclerView and show the user which item is currently selected. There are a few headaches:

  • Sets the effect of the Item when it gains focus
  • RecyclerView gets focus for the first time, the first item is selected by default
  • RecyclerView regaining focus, select the last item
  • RecyclerView lost focus, continue to maintain the selected item effect

9.1 Set the effect of Item when it gets focus

Just like a single View, we can set the SelectDrawable to the Item.

9.2 RecyclerView gets focus for the first time, the first item is selected by default

Since the focus jump rule of Android system is the nearby jump, a View close to RecyclerView may jump to an ItemView inside RecyclerView which is close to it. Not the first ItemView inside of RecyclerView. This clearly does not meet our requirements.

So how can we make RecyclerView get focus for the first time, select the first item that?

The answer is: HorizontalGridView or VerticalGridView. These two views are the two classes in leanback warehouse, both inherited from BaseGridView, and BaseGridView inherited from RecyclerView. HorizontalGridView is the focus of dealing with horizontal RecyclerView, VerticalGridView is dealing with vertical.

Add dependencies:

Implementation "androidx leanback: leanback: 1.0.0."Copy the code

use

 <androidx.leanback.widget.HorizontalGridView
        android:id="@+id/rvHead"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:nextFocusLeft="@id/rvHead"
        android:nextFocusRight="@id/rvHead"/>

Copy the code

Because the HorizontalGridView extends BaseGridView extends RecyclerView, the code that used to use RecyclerView basically doesn’t change and doesn’t call setLayoutManager. Never call setLayoutManager, it will not work. BaseGridView’s focus control is completely implemented by the LayoutManager set internally.)

9.3 RecyclerView after regain focus, select the last item

Something like this:

In the case of no processing, RecyclerView regain focus is also according to the recent principle to get focus, rather than the last selected View get focus.

To get RecyclerView back into focus, select the last item. Use either a HorizontalGridView or a VerticalGridView.

9.4 RecyclerView keep item selected after losing focus

I can think of two ways to do this

1. Only one View can remain selected at a time. When a View is selected, the previously selected View is deselected. So save the last selected View, when a new View is selected, the last selected View is unselected, when the new View loses focus, update it to the last selected View.

mRootView.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { v.setSelected(true); if (mLastFocusView! = null) { mLastFocusView.setSelected(false); } } else { mLastFocusView = v; }}});Copy the code

2, since only one ItemView can be selected at a time, then get the selected ItemView positon, RecyclerView all ItemView, as long as it is not selected positon, do not let it in the selected state.

The second method is more violent and the first method is recommended.

9. LeanBack Program

Warehouse address: github.com/android/tv-…

Post a paragraph of official explanation pack force….

This sample is a Videos By Google app, designed to run on an Android TV device, which demonstrates how to use the Leanback Support library which enables you to easily develop beautiful Android TV apps with a user-friendly UI that complies with the UX guidelines of Android TV.

This project is a video APP officially provided by Google for TV devices. The main purpose is to teach you how to use the Leanback library and develop a user-friendly, standardized Android TV APP with ease.

This library through some interface implementation methods, to help developers quickly achieve TV development. Here are some screenshots of the library’s interface.

Interested students can download to the local, experience.

10, recommend

Google TV development guide: developer.android.com/training/tv…

Android TV–RecyclerView item focus combat: juejin.cn/post/687811…

LeanbackShowcase:github.com/android/tv-…

TV – samples: github.com/android/tv-…