1--- 2title: UI components 3--- 4 5An app playing media requires user interface components for displaying media and 6controlling playback. The ExoPlayer library includes a UI module that contains 7a number of UI components. To depend on the UI module add a dependency as shown 8below. 9 10~~~ 11implementation 'com.google.android.exoplayer:exoplayer-ui:2.X.X' 12~~~ 13{: .language-gradle} 14 15The most important components are `StyledPlayerControlView`, `StyledPlayerView`, 16`PlayerControlView` and `PlayerView`. The styled variants provide a more 17polished user experience, however are harder to customize. 18 19* [`StyledPlayerControlView`][] and [`PlayerControlView`][] are views for 20 controlling playbacks. They display standard playback controls including a 21 play/pause button, fast-forward and rewind buttons, and a seek bar. 22* [`StyledPlayerView`][] and [`PlayerView`][] are high level views for 23 playbacks. They display video, subtitles and album art during playback, as 24 well as playback controls using a `StyledPlayerControlView` or 25 `PlayerControlView` respectively. 26 27All four views have a `setPlayer` method for attaching and detaching (by passing 28`null`) player instances. 29 30## Player views ## 31 32`StyledPlayerView` and `PlayerView` can be used for both video and audio 33playbacks. They render video and subtitles in the case of video playback, and 34can display artwork included as metadata in audio files. You can include them in 35your layout files like any other UI component. For example, a `StyledPlayerView` 36can be included with the following XML: 37 38~~~ 39<com.google.android.exoplayer2.ui.StyledPlayerView 40 android:id="@+id/player_view" 41 android:layout_width="match_parent" 42 android:layout_height="match_parent" 43 app:show_buffering="when_playing" 44 app:show_shuffle_button="true"/> 45~~~ 46{: .language-xml} 47 48The snippet above illustrates that `StyledPlayerView` provides several 49attributes. These attributes can be used to customize the view's behavior, as 50well as its look and feel. Most of these attributes have corresponding setter 51methods, which can be used to customize the view at runtime. The 52[`StyledPlayerView`][] Javadoc lists these attributes and setter methods in 53more detail. [`PlayerView`][] defines similar attributes. 54 55Once the view is declared in the layout file, it can be looked up in the 56`onCreate` method of the activity: 57 58~~~ 59@Override 60protected void onCreate(Bundle savedInstanceState) { 61 super.onCreate(savedInstanceState); 62 // ... 63 playerView = findViewById(R.id.player_view); 64} 65~~~ 66{: .language-java} 67 68When a player has been initialized, it can be attached to the view by calling 69`setPlayer`: 70 71~~~ 72// Instantiate the player. 73player = new ExoPlayer.Builder(context).build(); 74// Attach player to the view. 75playerView.setPlayer(player); 76// Set the media item to be played. 77player.setMediaItem(mediaItem); 78// Prepare the player. 79player.prepare(); 80~~~ 81{: .language-java} 82 83### Choosing a surface type ### 84 85The `surface_type` attribute of `StyledPlayerView` and `PlayerView` lets you set 86the type of surface used for video playback. Besides the values 87`spherical_gl_surface_view` (which is a special value for spherical video 88playback) and `video_decoder_gl_surface_view` (which is for video rendering 89using extension renderers), the allowed values are `surface_view`, 90`texture_view` and `none`. If the view is for audio playback only, `none` should 91be used to avoid having to create a surface, since doing so can be expensive. 92 93If the view is for regular video playback then `surface_view` or `texture_view` 94should be used. `SurfaceView` has a number of benefits over `TextureView` for 95video playback: 96 97* Significantly lower power consumption on many devices. 98* More accurate frame timing, resulting in smoother video playback. 99* Support for secure output when playing DRM protected content. 100* The ability to render video content at the full resolution of the display on 101 Android TV devices that upscale the UI layer. 102 103`SurfaceView` should therefore be preferred over `TextureView` where possible. 104`TextureView` should be used only if `SurfaceView` does not meet your needs. One 105example is where smooth animations or scrolling of the video surface is required 106prior to Android N, as described below. For this case, it's preferable to use 107`TextureView` only when [`SDK_INT`][] is less than 24 (Android N) and 108`SurfaceView` otherwise. 109 110`SurfaceView` rendering wasn't properly synchronized with view animations until 111Android N. On earlier releases this could result in unwanted effects when a 112`SurfaceView` was placed into scrolling container, or when it was subjected to 113animation. Such effects included the view's contents appearing to lag slightly 114behind where it should be displayed, and the view turning black when subjected 115to animation. To achieve smooth animation or scrolling of video prior to Android 116N, it's therefore necessary to use `TextureView` rather than `SurfaceView`. 117{:.info} 118 119Some Android TV devices run their UI layer at a resolution that's lower than the 120full resolution of the display, upscaling it for presentation to the user. For 121example, the UI layer may be run at 1080p on an Android TV that has a 4K 122display. On such devices, `SurfaceView` must be used to render content at the 123full resolution of the display. The full resolution of the display (in its 124current display mode) can be queried using [`Util.getCurrentDisplayModeSize`][]. 125The UI layer resolution can be queried using Android's [`Display.getSize`] API. 126{:.info} 127 128## Player control views ## 129 130When using `StyledPlayerView`, a `StyledPlayerControlView` is used internally to 131provide playback controls. When using a `PlayerView`, a `PlayerControlView` is 132used internally. 133 134For specific use cases `StyledPlayerControlView` and `PlayerControlView` can 135also be used as standalone components. They can be included in your layout file 136as normal. For example: 137 138~~~ 139<com.google.android.exoplayer2.ui.StyledPlayerControlView 140 android:id="@+id/player_control_view" 141 android:layout_width="match_parent" 142 android:layout_height="match_parent"/> 143~~~ 144{: .language-xml} 145 146The [`StyledPlayerControlView`][] and [`PlayerControlView`][] Javadoc list the 147the available attributes and setter methods for these components. Looking them 148up and attaching the player is similar to the example above: 149 150~~~ 151@Override 152protected void onCreate(Bundle savedInstanceState) { 153 super.onCreate(savedInstanceState); 154 // ... 155 playerControlView = findViewById(R.id.player_control_view); 156} 157 158private void initializePlayer() { 159 // Instantiate the player. 160 player = new ExoPlayer.Builder(context).build(); 161 // Attach player to the view. 162 playerControlView.setPlayer(player); 163 // Set the media item to be played. 164 player.setMediaItem(mediaItem); 165 // Prepare the player. 166 player.prepare(); 167} 168~~~ 169{: .language-java} 170 171## Customization ## 172 173Where significant customization is required, we expect that app developers will 174implement their own UI components rather than using those provided by 175ExoPlayer's UI module. That said, the provided UI components do allow for 176customization by setting attributes (as described above), overriding drawables, 177overriding layout files, and by specifying custom layout files. 178 179### Overriding drawables ### 180 181The drawables used by `StyledPlayerControlView` and `PlayerControlView` 182(with their default layout files) can be overridden by drawables with the same 183names defined in your application. See the [`StyledPlayerControlView`][] and 184[`PlayerControlView`][] Javadoc for a list of drawables that can be overridden. 185Note that overriding these drawables will also affect the appearance of 186`PlayerView` and `StyledPlayerView`, since they use these views internally. 187 188### Overriding layout files ### 189 190All of the view components inflate their layouts from corresponding layout 191files, which are specified in their Javadoc. For example when a 192`PlayerControlView` is instantiated, it inflates its layout from 193`exo_player_control_view.xml`. To customize these layouts, an application 194can define layout files with the same names in its own `res/layout*` 195directories. These layout files will override the ones provided by the ExoPlayer 196library. 197 198As an example, suppose we want our playback controls to consist of only a 199play/pause button positioned in the center of the view. We can achieve this by 200creating an `exo_player_control_view.xml` file in the application’s 201`res/layout` directory, containing: 202 203~~~ 204<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 205 android:layout_width="match_parent" 206 android:layout_height="match_parent"> 207 208 <ImageButton android:id="@id/exo_play" 209 android:layout_width="100dp" 210 android:layout_height="100dp" 211 android:layout_gravity="center" 212 android:background="#CC000000" 213 style="@style/ExoMediaButton.Play"/> 214 215 <ImageButton android:id="@id/exo_pause" 216 android:layout_width="100dp" 217 android:layout_height="100dp" 218 android:layout_gravity="center" 219 android:background="#CC000000" 220 style="@style/ExoMediaButton.Pause"/> 221 222</FrameLayout> 223~~~ 224{: .language-xml} 225 226The change in visual appearance compared to the standard controls is shown 227below. 228 229{% include figure.html url="/images/overriding-layoutfiles.png" index="1" caption="Replacing the standard playback controls (left) with custom controls (right)" %} 230 231### Custom layout files ### 232 233Overriding a layout file is an excellent solution for changing the layout across 234the whole of an application, but what if a custom layout is required only in a 235single place? To achieve this, first define a layout file as though overriding 236one of the default layouts, but this time giving it a different file name, for 237example `custom_controls.xml`. Second, use an attribute to indicate that this 238layout should be used when inflating the view. For example when using 239`PlayerView`, the layout inflated to provide the playback controls can be 240specified using the `controller_layout_id` attribute: 241 242~~~ 243<com.google.android.exoplayer2.ui.PlayerView android:id="@+id/player_view" 244 android:layout_width="match_parent" 245 android:layout_height="match_parent" 246 app:controller_layout_id="@layout/custom_controls"/> 247~~~ 248{: .language-xml} 249 250[`PlayerView`]: {{ site.exo_sdk }}/ui/PlayerView.html 251[`PlayerControlView`]: {{ site.exo_sdk }}/ui/PlayerControlView.html 252[`StyledPlayerView`]: {{ site.exo_sdk }}/ui/StyledPlayerView.html 253[`StyledPlayerControlView`]: {{ site.exo_sdk }}/ui/StyledPlayerControlView.html 254[`SDK_INT`]: {{ site.android_sdk }}/android/os/Build.VERSION.html#SDK_INT 255[`Util.getCurrentDisplayModeSize`]: {{ site.exo_sdk }}/util/Util.html#getCurrentDisplayModeSize(android.content.Context) 256[`Display.getSize`]: {{ site.android_sdk }}/android/view/Display.html#getSize(android.graphics.Point) 257