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