Twelve: Main fragment tablet UI
diff --git a/app/src/main/java/org/lineageos/twelve/fragments/MainFragment.kt b/app/src/main/java/org/lineageos/twelve/fragments/MainFragment.kt
index 3db2677..b32eb76 100644
--- a/app/src/main/java/org/lineageos/twelve/fragments/MainFragment.kt
+++ b/app/src/main/java/org/lineageos/twelve/fragments/MainFragment.kt
@@ -7,6 +7,8 @@
import android.os.Bundle
import android.view.View
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
@@ -17,12 +19,14 @@
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.appbar.MaterialToolbar
-import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.button.MaterialButton
+import com.google.android.material.navigation.NavigationBarView
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.lineageos.twelve.R
import org.lineageos.twelve.ext.getViewProperty
+import org.lineageos.twelve.ext.isLandscape
+import org.lineageos.twelve.ext.updatePadding
import org.lineageos.twelve.models.RequestStatus
import org.lineageos.twelve.ui.views.NowPlayingBar
import org.lineageos.twelve.viewmodels.NowPlayingViewModel
@@ -37,7 +41,7 @@
private val providersViewModel by viewModels<ProvidersViewModel>()
// Views
- private val bottomNavigationView by getViewProperty<BottomNavigationView>(R.id.bottomNavigationView)
+ private val navigationBarView by getViewProperty<NavigationBarView>(R.id.navigationBarView)
private val nowPlayingBar by getViewProperty<NowPlayingBar>(R.id.nowPlayingBar)
private val providerMaterialButton by getViewProperty<MaterialButton>(R.id.providerMaterialButton)
private val toolbar by getViewProperty<MaterialToolbar>(R.id.toolbar)
@@ -49,7 +53,7 @@
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
- bottomNavigationView.menu.getItem(position).isChecked = true
+ navigationBarView.menu.getItem(position).isChecked = true
}
}
}
@@ -57,6 +61,49 @@
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+ // Insets
+ ViewCompat.setOnApplyWindowInsetsListener(toolbar) { v, windowInsets ->
+ val insets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout())
+
+ v.updatePadding(
+ insets,
+ start = !resources.configuration.isLandscape,
+ end = true,
+ )
+
+ windowInsets
+ }
+
+ if (resources.configuration.isLandscape) {
+ ViewCompat.setOnApplyWindowInsetsListener(navigationBarView) { v, windowInsets ->
+ // This is a navigation rail
+ val insets = windowInsets.getInsets(
+ WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout()
+ )
+
+ v.updatePadding(
+ insets,
+ start = true,
+ top = true,
+ bottom = true,
+ )
+
+ windowInsets
+ }
+ }
+
+ ViewCompat.setOnApplyWindowInsetsListener(viewPager2) { v, windowInsets ->
+ val insets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout())
+
+ v.updatePadding(
+ insets,
+ start = !resources.configuration.isLandscape,
+ end = true,
+ )
+
+ windowInsets
+ }
+
toolbar.setupWithNavController(findNavController())
providerMaterialButton.setOnClickListener {
@@ -73,7 +120,7 @@
viewPager2.offscreenPageLimit = fragments.size
viewPager2.registerOnPageChangeCallback(onPageChangeCallback)
- bottomNavigationView.setOnItemSelectedListener { item ->
+ navigationBarView.setOnItemSelectedListener { item ->
when (item.itemId) {
R.id.activityFragment -> {
viewPager2.currentItem = 0
diff --git a/app/src/main/java/org/lineageos/twelve/ui/views/NowPlayingBar.kt b/app/src/main/java/org/lineageos/twelve/ui/views/NowPlayingBar.kt
index 12df33f..24655ec 100644
--- a/app/src/main/java/org/lineageos/twelve/ui/views/NowPlayingBar.kt
+++ b/app/src/main/java/org/lineageos/twelve/ui/views/NowPlayingBar.kt
@@ -8,11 +8,15 @@
import android.content.Context
import android.graphics.ImageDecoder
import android.util.AttributeSet
+import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
+import androidx.core.view.updateLayoutParams
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import com.google.android.material.card.MaterialCardView
@@ -33,9 +37,45 @@
private val thumbnailImageView by lazy { findViewById<ImageView>(R.id.thumbnailImageView) }
private val titleTextView by lazy { findViewById<TextView>(R.id.titleTextView) }
+ private var isBottomNavigationBar = false
+
init {
inflate(context, R.layout.now_playing_bar, this)
+ context.obtainStyledAttributes(attrs, R.styleable.NowPlayingBar, 0, 0).apply {
+ try {
+ isBottomNavigationBar = getBoolean(
+ R.styleable.NowPlayingBar_isBottomNavigationBar,
+ false
+ )
+ } finally {
+ recycle()
+ }
+ }
+
+ ViewCompat.setOnApplyWindowInsetsListener(this) { _, windowInsets ->
+ val insets = windowInsets.getInsets(
+ WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout()
+ )
+
+ updateLayoutParams<MarginLayoutParams> {
+ leftMargin = insets.left
+ rightMargin = insets.right
+ }
+
+ materialCardView.setContentPadding(
+ 0,
+ 0,
+ 0,
+ when (isBottomNavigationBar) {
+ true -> insets.bottom
+ false -> 0
+ }
+ )
+
+ windowInsets
+ }
+
circularProgressIndicator.min = 0
}
diff --git a/app/src/main/res/layout-land/fragment_main.xml b/app/src/main/res/layout-land/fragment_main.xml
new file mode 100644
index 0000000..72bc605
--- /dev/null
+++ b/app/src/main/res/layout-land/fragment_main.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ SPDX-FileCopyrightText: 2024 The LineageOS Project
+ SPDX-License-Identifier: Apache-2.0
+-->
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.google.android.material.appbar.AppBarLayout
+ android:id="@+id/appBarLayout"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:fitsSystemWindows="true"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="@+id/viewPager2"
+ app:layout_constraintTop_toTopOf="parent">
+
+ <com.google.android.material.appbar.MaterialToolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ tools:title="@string/app_name">
+
+ <com.google.android.material.button.MaterialButton
+ android:id="@+id/providerMaterialButton"
+ style="@style/Widget.Material3.Button.TextButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end"
+ android:layout_marginHorizontal="16dp"
+ tools:icon="@drawable/ic_shelves"
+ tools:text="Pixel 7 Pro" />
+
+ </com.google.android.material.appbar.MaterialToolbar>
+
+ </com.google.android.material.appbar.AppBarLayout>
+
+ <androidx.viewpager2.widget.ViewPager2
+ android:id="@+id/viewPager2"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ app:layout_constraintBottom_toTopOf="@+id/nowPlayingBar"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@+id/navigationBarView"
+ app:layout_constraintTop_toBottomOf="@+id/appBarLayout" />
+
+ <org.lineageos.twelve.ui.views.NowPlayingBar
+ android:id="@+id/nowPlayingBar"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:paddingHorizontal="24dp"
+ app:isBottomNavigationBar="true"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent" />
+
+ <com.google.android.material.navigationrail.NavigationRailView
+ android:id="@+id/navigationBarView"
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ app:layout_constraintBottom_toTopOf="@+id/nowPlayingBar"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:menu="@menu/navigation_bar_view_fragment_main"
+ app:menuGravity="top"
+ app:paddingBottomSystemWindowInsets="false"
+ app:paddingTopSystemWindowInsets="false" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml
index f768670..f5bfa8e 100644
--- a/app/src/main/res/layout/fragment_main.xml
+++ b/app/src/main/res/layout/fragment_main.xml
@@ -22,7 +22,7 @@
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- tools:title="@string/app_name" >
+ tools:title="@string/app_name">
<com.google.android.material.button.MaterialButton
android:id="@+id/providerMaterialButton"
@@ -52,17 +52,17 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="gone"
- app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
+ app:layout_constraintBottom_toTopOf="@+id/navigationBarView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.google.android.material.bottomnavigation.BottomNavigationView
- android:id="@+id/bottomNavigationView"
+ android:id="@+id/navigationBarView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:menu="@menu/bottom_navigation_view_fragment_main" />
+ app:menu="@menu/navigation_bar_view_fragment_main" />
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/menu/bottom_navigation_view_fragment_main.xml b/app/src/main/res/menu/navigation_bar_view_fragment_main.xml
similarity index 100%
rename from app/src/main/res/menu/bottom_navigation_view_fragment_main.xml
rename to app/src/main/res/menu/navigation_bar_view_fragment_main.xml
diff --git a/app/src/main/res/values/attrs_NowPlayingBar.xml b/app/src/main/res/values/attrs_NowPlayingBar.xml
new file mode 100644
index 0000000..4eed890
--- /dev/null
+++ b/app/src/main/res/values/attrs_NowPlayingBar.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ SPDX-FileCopyrightText: 2024 The LineageOS Project
+ SPDX-License-Identifier: Apache-2.0
+-->
+<resources>
+ <declare-styleable name="NowPlayingBar">
+ <attr name="isBottomNavigationBar" format="boolean" />
+ </declare-styleable>
+</resources>