Skip to content

Commit eba4467

Browse files
alperozturk96backportbot[bot]
authored andcommitted
redesign re-use ui components
Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
1 parent 837557d commit eba4467

7 files changed

Lines changed: 119 additions & 135 deletions

File tree

app/src/main/java/com/nextcloud/client/player/ui/video/VideoFileFragment.kt

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import android.view.LayoutInflater
1212
import android.view.View
1313
import android.view.ViewGroup
1414
import androidx.core.os.bundleOf
15+
import androidx.core.view.isVisible
1516
import androidx.fragment.app.Fragment
1617
import androidx.lifecycle.lifecycleScope
1718
import com.nextcloud.client.player.media3.PlaybackModel
@@ -33,6 +34,8 @@ class VideoFileFragment :
3334

3435
companion object {
3536
private const val ARGUMENT_FILE = "ARGUMENT_FILE"
37+
private const val SURFACE_ALPHA_VISIBLE = 1f
38+
private const val SURFACE_ALPHA_HIDDEN = 0f
3639

3740
fun createInstance(file: PlaybackFile) = VideoFileFragment().apply {
3841
arguments = bundleOf(ARGUMENT_FILE to file)
@@ -45,23 +48,28 @@ class VideoFileFragment :
4548
@Inject
4649
lateinit var thumbnailLoader: ThumbnailLoader
4750

48-
private lateinit var file: PlaybackFile
49-
50-
private lateinit var binding: PlayerVideoFileFragmentBinding
51+
private var _binding: PlayerVideoFileFragmentBinding? = null
52+
private val binding get() = checkNotNull(_binding) { "Binding accessed outside of the view lifecycle" }
5153

5254
private var previousVideoSize: VideoSize? = null
5355

56+
private val file by lazy {
57+
requireNotNull(arguments.getSerializableArgument(ARGUMENT_FILE, PlaybackFile::class.java)) {
58+
"VideoFileFragment requires a $ARGUMENT_FILE argument"
59+
}
60+
}
61+
5462
override fun onCreate(savedInstanceState: Bundle?) {
5563
super.onCreate(savedInstanceState)
5664
AndroidSupportInjection.inject(this)
57-
val playbackFile = arguments.getSerializableArgument(ARGUMENT_FILE, PlaybackFile::class.java)
58-
this.file = playbackFile ?: throw IllegalArgumentException("bundle is not containing playback file")
5965
}
6066

61-
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
62-
binding = PlayerVideoFileFragmentBinding.inflate(inflater, container, false)
67+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
68+
PlayerVideoFileFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
69+
70+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
71+
super.onViewCreated(view, savedInstanceState)
6372
loadFileThumbnail()
64-
return binding.root
6573
}
6674

6775
override fun onStart() {
@@ -75,39 +83,43 @@ class VideoFileFragment :
7583
super.onStop()
7684
}
7785

86+
override fun onDestroyView() {
87+
_binding = null
88+
super.onDestroyView()
89+
}
90+
7891
override fun onPlaybackUpdate(state: PlaybackState) {
7992
render(state)
8093
}
8194

82-
private fun loadFileThumbnail() {
83-
viewLifecycleOwner.lifecycleScope.launch {
84-
val context = context ?: return@launch
85-
val thumbnailSize = context.resources.getDimension(R.dimen.player_album_cover_size)
86-
val thumbnail = thumbnailLoader.await(context, file, thumbnailSize.toInt(), thumbnailSize.toInt())
87-
thumbnail?.let(binding.thumbnail::setImageBitmap)
88-
}
95+
private fun loadFileThumbnail() = viewLifecycleOwner.lifecycleScope.launch {
96+
val thumbnailSize = resources.getDimensionPixelSize(R.dimen.player_album_cover_size)
97+
val thumbnail = thumbnailLoader.await(requireContext(), file, thumbnailSize, thumbnailSize) ?: return@launch
98+
binding.thumbnail.setImageBitmap(thumbnail)
8999
}
90100

91101
private fun render(state: PlaybackState?) {
92102
val currentItemState = state?.currentItemState
103+
93104
if (currentItemState?.file == file) {
94105
showVideo(currentItemState.videoSize)
95-
} else {
96-
binding.surfaceView.visibility = View.GONE
97-
if (currentItemState == null) {
98-
playerModel.setVideoSurfaceView(null)
99-
}
106+
return
107+
}
108+
109+
binding.surfaceView.isVisible = false
110+
if (currentItemState == null) {
111+
playerModel.setVideoSurfaceView(null)
100112
}
101113
}
102114

103115
private fun showVideo(videoSize: VideoSize?) {
104116
playerModel.setVideoSurfaceView(binding.surfaceView)
105-
binding.surfaceView.visibility = View.VISIBLE
106-
binding.surfaceView.alpha = if (videoSize != null) 1f else 0f
117+
binding.surfaceView.isVisible = true
118+
binding.surfaceView.alpha = if (videoSize == null) SURFACE_ALPHA_HIDDEN else SURFACE_ALPHA_VISIBLE
107119

108-
if (videoSize != null && previousVideoSize != videoSize) {
109-
previousVideoSize = videoSize
110-
binding.surfaceView.applyVideoSize(videoSize)
111-
}
120+
if (videoSize == null || previousVideoSize == videoSize) return
121+
122+
previousVideoSize = videoSize
123+
binding.surfaceView.applyVideoSize(videoSize)
112124
}
113125
}

app/src/main/java/com/nextcloud/client/player/ui/video/VideoPlayerView.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ class VideoPlayerView(context: Context) : PlayerView(context) {
3434

3535
private var hideControlsTimerJob: Job? = null
3636

37+
init {
38+
topBar.setBackgroundResource(R.color.player_video_toolbar_background_color)
39+
}
40+
3741
override fun onStart() {
3842
super.onStart()
3943
showControls()
Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,17 @@
11
<?xml version="1.0" encoding="utf-8"?><!--
22
~ Nextcloud - Android Client
33
~
4-
~ SPDX-FileCopyrightText: 2025 STRATO GmbH.
5-
~ SPDX-License-Identifier: GPL-2.0
4+
~ SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
5+
~ SPDX-License-Identifier: AGPL-3.0-or-later
66
-->
77

88
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
9-
xmlns:app="http://schemas.android.com/apk/res-auto"
10-
xmlns:tools="http://schemas.android.com/tools"
119
android:layout_width="match_parent"
1210
android:layout_height="match_parent"
1311
android:background="@color/player_background_color"
1412
android:orientation="vertical">
1513

16-
<LinearLayout
17-
android:id="@+id/topBar"
18-
android:layout_width="match_parent"
19-
android:layout_height="wrap_content"
20-
android:gravity="center_vertical"
21-
android:minHeight="@dimen/player_toolbar_height"
22-
android:orientation="horizontal">
23-
24-
<com.google.android.material.button.MaterialButton
25-
android:id="@+id/back"
26-
style="@style/Widget.AppTheme.Button.IconButton"
27-
android:layout_width="wrap_content"
28-
android:layout_height="wrap_content"
29-
android:layout_marginStart="@dimen/player_back_button_margin_start"
30-
android:layout_marginEnd="@dimen/player_back_button_margin_end"
31-
app:icon="@drawable/ic_arrow_back"
32-
app:iconSize="24dp"
33-
app:iconTint="@color/player_toolbar_icon_color" />
34-
35-
<TextView
36-
android:id="@+id/title"
37-
android:layout_width="0dp"
38-
android:layout_height="match_parent"
39-
android:layout_weight="1"
40-
android:ellipsize="end"
41-
android:gravity="center_vertical"
42-
android:singleLine="true"
43-
android:textColor="@color/player_toolbar_text_color"
44-
android:textSize="@dimen/player_toolbar_text_size"
45-
tools:text="Audio Player" />
46-
47-
<com.google.android.material.button.MaterialButton
48-
android:id="@+id/more"
49-
style="@style/Widget.AppTheme.Button.IconButton"
50-
android:layout_width="wrap_content"
51-
android:layout_height="wrap_content"
52-
app:icon="@drawable/ic_dots_vertical"
53-
app:iconSize="24dp"
54-
app:iconTint="@color/player_toolbar_icon_color" />
55-
56-
</LinearLayout>
14+
<include layout="@layout/player_top_bar" />
5715

5816
<com.nextcloud.client.player.ui.pager.PlayerPager
5917
android:id="@+id/playerPager"
@@ -65,7 +23,6 @@
6523
android:id="@+id/playerControlView"
6624
android:layout_width="match_parent"
6725
android:layout_height="wrap_content"
68-
android:layout_gravity="bottom"
6926
android:background="@color/player_background_color" />
7027

7128
</LinearLayout>

app/src/main/res/layout/player_control_view.xml

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
<?xml version="1.0" encoding="utf-8"?><!--
22
~ Nextcloud - Android Client
33
~
4-
~ SPDX-FileCopyrightText: 2025 STRATO GmbH.
5-
~ SPDX-License-Identifier: GPL-2.0
4+
~ SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
5+
~ SPDX-License-Identifier: AGPL-3.0-or-later
66
-->
77

88
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
9+
xmlns:app="http://schemas.android.com/apk/res-auto"
910
android:layout_width="match_parent"
1011
android:layout_height="wrap_content"
11-
xmlns:app="http://schemas.android.com/apk/res-auto"
12-
android:background="@color/transparent"
1312
android:orientation="vertical">
1413

1514
<LinearLayout
@@ -22,7 +21,7 @@
2221
android:paddingStart="@dimen/player_progress_panel_padding_horizontal"
2322
android:paddingEnd="@dimen/player_progress_panel_padding_horizontal">
2423

25-
<TextView
24+
<com.google.android.material.textview.MaterialTextView
2625
android:id="@+id/tvElapsed"
2726
style="@style/PlayerTimeTextViewStyle" />
2827

@@ -32,12 +31,9 @@
3231
android:layout_width="0dp"
3332
android:layout_height="@dimen/player_progressbar_height"
3433
android:layout_weight="1"
35-
android:indeterminate="false"
36-
android:longClickable="false"
37-
android:max="100"
38-
android:progress="0" />
34+
android:longClickable="false" />
3935

40-
<TextView
36+
<com.google.android.material.textview.MaterialTextView
4137
android:id="@+id/tvTotalTime"
4238
style="@style/PlayerTimeTextViewStyle" />
4339

@@ -53,32 +49,32 @@
5349

5450
<com.google.android.material.button.MaterialButton
5551
android:id="@+id/ivRepeat"
56-
android:contentDescription="@string/player_control_view_repeat_button_content_description"
5752
style="@style/PlayerButtonStyle"
53+
android:contentDescription="@string/player_control_view_repeat_button_content_description"
5854
app:icon="@drawable/player_ic_repeat" />
5955

6056
<com.google.android.material.button.MaterialButton
6157
android:id="@+id/ivPrevious"
62-
android:contentDescription="@string/player_control_view_previous_button_content_description"
6358
style="@style/PlayerButtonStyle"
59+
android:contentDescription="@string/player_control_view_previous_button_content_description"
6460
app:icon="@drawable/player_ic_skip_previous" />
6561

6662
<com.google.android.material.button.MaterialButton
6763
android:id="@+id/ivPlayPause"
68-
android:contentDescription="@string/player_control_view_play_pause_button_content_description"
6964
style="@style/PlayerButtonStyle"
65+
android:contentDescription="@string/player_control_view_play_pause_button_content_description"
7066
app:icon="@drawable/player_ic_play" />
7167

7268
<com.google.android.material.button.MaterialButton
7369
android:id="@+id/ivNext"
74-
android:contentDescription="@string/player_control_view_next_button_content_description"
7570
style="@style/PlayerButtonStyle"
71+
android:contentDescription="@string/player_control_view_next_button_content_description"
7672
app:icon="@drawable/player_ic_skip_next" />
7773

7874
<com.google.android.material.button.MaterialButton
7975
android:id="@+id/ivRandom"
80-
android:contentDescription="@string/player_control_view_random_button_content_description"
8176
style="@style/PlayerButtonStyle"
77+
android:contentDescription="@string/player_control_view_random_button_content_description"
8278
app:icon="@drawable/player_ic_shuffle" />
8379

8480
</LinearLayout>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?xml version="1.0" encoding="utf-8"?><!--
2+
~ Nextcloud - Android Client
3+
~
4+
~ SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
5+
~ SPDX-License-Identifier: AGPL-3.0-or-later
6+
-->
7+
8+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
9+
xmlns:app="http://schemas.android.com/apk/res-auto"
10+
xmlns:tools="http://schemas.android.com/tools"
11+
android:id="@+id/topBar"
12+
android:layout_width="match_parent"
13+
android:layout_height="wrap_content"
14+
android:gravity="center_vertical"
15+
android:minHeight="@dimen/player_toolbar_height"
16+
android:orientation="horizontal">
17+
18+
<com.google.android.material.button.MaterialButton
19+
android:id="@+id/back"
20+
style="@style/PlayerToolbarIconButtonStyle"
21+
android:layout_marginStart="@dimen/player_back_button_margin_start"
22+
android:layout_marginEnd="@dimen/player_back_button_margin_end"
23+
android:contentDescription="@string/common_back"
24+
app:icon="@drawable/ic_arrow_back" />
25+
26+
<com.google.android.material.textview.MaterialTextView
27+
android:id="@+id/title"
28+
android:layout_width="0dp"
29+
android:layout_height="match_parent"
30+
android:layout_weight="1"
31+
android:ellipsize="end"
32+
android:gravity="center_vertical"
33+
android:singleLine="true"
34+
android:textAppearance="@style/TextAppearance.App.Player.Toolbar"
35+
tools:text="Player title" />
36+
37+
<com.google.android.material.button.MaterialButton
38+
android:id="@+id/more"
39+
style="@style/PlayerToolbarIconButtonStyle"
40+
android:contentDescription="@string/overflow_menu"
41+
app:icon="@drawable/ic_dots_vertical" />
42+
43+
</LinearLayout>

app/src/main/res/layout/player_video_view.xml

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
<?xml version="1.0" encoding="utf-8"?><!--
22
~ Nextcloud - Android Client
33
~
4-
~ SPDX-FileCopyrightText: 2025 STRATO GmbH.
5-
~ SPDX-License-Identifier: GPL-2.0
4+
~ SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
5+
~ SPDX-License-Identifier: AGPL-3.0-or-later
66
-->
77

88
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
9-
xmlns:app="http://schemas.android.com/apk/res-auto"
10-
xmlns:tools="http://schemas.android.com/tools"
119
android:layout_width="match_parent"
1210
android:layout_height="match_parent"
1311
android:background="@color/player_background_color">
@@ -17,48 +15,7 @@
1715
android:layout_width="match_parent"
1816
android:layout_height="match_parent" />
1917

20-
<LinearLayout
21-
android:id="@+id/topBar"
22-
android:layout_width="match_parent"
23-
android:layout_height="wrap_content"
24-
android:background="@color/player_video_toolbar_background_color"
25-
android:gravity="center_vertical"
26-
android:minHeight="@dimen/player_toolbar_height"
27-
android:orientation="horizontal">
28-
29-
<com.google.android.material.button.MaterialButton
30-
android:id="@+id/back"
31-
style="@style/Widget.AppTheme.Button.IconButton"
32-
android:layout_width="wrap_content"
33-
android:layout_height="wrap_content"
34-
android:layout_marginStart="@dimen/player_back_button_margin_start"
35-
android:layout_marginEnd="@dimen/player_back_button_margin_end"
36-
app:icon="@drawable/ic_arrow_back"
37-
app:iconSize="24dp"
38-
app:iconTint="@color/player_toolbar_icon_color" />
39-
40-
<TextView
41-
android:id="@+id/title"
42-
android:layout_width="0dp"
43-
android:layout_height="match_parent"
44-
android:layout_weight="1"
45-
android:ellipsize="end"
46-
android:gravity="center_vertical"
47-
android:singleLine="true"
48-
android:textColor="@color/player_toolbar_text_color"
49-
android:textSize="@dimen/player_toolbar_text_size"
50-
tools:text="Video Player" />
51-
52-
<com.google.android.material.button.MaterialButton
53-
android:id="@+id/more"
54-
style="@style/Widget.AppTheme.Button.IconButton"
55-
android:layout_width="wrap_content"
56-
android:layout_height="wrap_content"
57-
app:icon="@drawable/ic_dots_vertical"
58-
app:iconSize="24dp"
59-
app:iconTint="@color/player_toolbar_icon_color" />
60-
61-
</LinearLayout>
18+
<include layout="@layout/player_top_bar" />
6219

6320
<com.nextcloud.client.player.ui.control.PlayerControlView
6421
android:id="@+id/playerControlView"

0 commit comments

Comments
 (0)