From 4323e778a79e56a2cbdb3353d1044ee36ba0bff8 Mon Sep 17 00:00:00 2001 From: tekstrand Date: Thu, 20 Aug 2026 18:23:17 -0500 Subject: [PATCH 01/44] Added a navigation rail for tablets in landscape. A new layout-sw600dp-land variant of the main activity layout puts a NavigationRailView on the left edge, so wide screens spend horizontal space on navigation instead of a full-width bottom bar. Portrait and phones keep the bottom bar, which now always shows its labels via labelVisibilityMode. The activity and fragments reference the nav view as NavigationBarView, the superclass both widgets share, so the same code drives either one. --- .../java/com/js8call/example/MainActivity.kt | 4 +-- .../com/js8call/example/ui/DecodeFragment.kt | 4 +-- .../js8call/example/ui/MessagesFragment.kt | 2 +- .../res/layout-sw600dp-land/activity_main.xml | 30 +++++++++++++++++++ .../app/src/main/res/layout/activity_main.xml | 1 + 5 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 android/app/src/main/res/layout-sw600dp-land/activity_main.xml diff --git a/android/app/src/main/java/com/js8call/example/MainActivity.kt b/android/app/src/main/java/com/js8call/example/MainActivity.kt index 24dac83c0..06e63446a 100644 --- a/android/app/src/main/java/com/js8call/example/MainActivity.kt +++ b/android/app/src/main/java/com/js8call/example/MainActivity.kt @@ -17,7 +17,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.navigation.fragment.NavHostFragment import androidx.navigation.ui.setupWithNavController import androidx.preference.PreferenceManager -import com.google.android.material.bottomnavigation.BottomNavigationView +import com.google.android.material.navigation.NavigationBarView import com.google.android.material.snackbar.Snackbar import com.js8call.example.model.EngineState import com.js8call.example.service.JS8EngineService @@ -28,7 +28,7 @@ import com.js8call.example.ui.TransmitViewModel class MainActivity : AppCompatActivity() { - private lateinit var bottomNav: BottomNavigationView + private lateinit var bottomNav: NavigationBarView private lateinit var decodeViewModel: DecodeViewModel private lateinit var monitorViewModel: MonitorViewModel private var spectrumBroadcastCount: Long = 0 diff --git a/android/app/src/main/java/com/js8call/example/ui/DecodeFragment.kt b/android/app/src/main/java/com/js8call/example/ui/DecodeFragment.kt index 88906949c..e46303707 100644 --- a/android/app/src/main/java/com/js8call/example/ui/DecodeFragment.kt +++ b/android/app/src/main/java/com/js8call/example/ui/DecodeFragment.kt @@ -14,7 +14,7 @@ import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.floatingactionbutton.FloatingActionButton -import com.google.android.material.bottomnavigation.BottomNavigationView +import com.google.android.material.navigation.NavigationBarView import com.google.android.material.snackbar.Snackbar import com.js8call.example.R @@ -150,7 +150,7 @@ class DecodeFragment : Fragment() { return } transmitViewModel.setDirectedTo(callsign) - val bottomNav = activity?.findViewById(R.id.bottom_navigation) + val bottomNav = activity?.findViewById(R.id.bottom_navigation) if (bottomNav != null) { bottomNav.selectedItemId = R.id.navigation_transmit } else { diff --git a/android/app/src/main/java/com/js8call/example/ui/MessagesFragment.kt b/android/app/src/main/java/com/js8call/example/ui/MessagesFragment.kt index ae1594558..fc623f8fe 100644 --- a/android/app/src/main/java/com/js8call/example/ui/MessagesFragment.kt +++ b/android/app/src/main/java/com/js8call/example/ui/MessagesFragment.kt @@ -60,7 +60,7 @@ class MessagesFragment : Fragment() { // Set up FAB (navigate to Transmit tab to compose new message) newMessageFab.setOnClickListener { // Navigate to Transmit tab for new message - val bottomNav = activity?.findViewById(R.id.bottom_navigation) + val bottomNav = activity?.findViewById(R.id.bottom_navigation) bottomNav?.selectedItemId = R.id.navigation_transmit } diff --git a/android/app/src/main/res/layout-sw600dp-land/activity_main.xml b/android/app/src/main/res/layout-sw600dp-land/activity_main.xml new file mode 100644 index 000000000..ea00c528c --- /dev/null +++ b/android/app/src/main/res/layout-sw600dp-land/activity_main.xml @@ -0,0 +1,30 @@ + + + + + + + + diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml index 1e2de4c1f..549adc740 100644 --- a/android/app/src/main/res/layout/activity_main.xml +++ b/android/app/src/main/res/layout/activity_main.xml @@ -23,6 +23,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" + app:labelVisibilityMode="labeled" app:menu="@menu/bottom_nav_menu" /> From 8fe97f6317cd2b237ebe2191c5ea747eb0193f2b Mon Sep 17 00:00:00 2001 From: tekstrand Date: Thu, 20 Aug 2026 19:58:18 -0500 Subject: [PATCH 02/44] Merged the Decodes tab into the Monitor tab. The decode list is embedded in the Monitor screen through a FragmentContainerView, so its reply, copy, time-sync, and clear behavior carries over unchanged. In tablet landscape the waterfall keeps the full width, with the status card and start button in a left column and the decode list on the right. Portrait stacks waterfall, status, decodes, and the start button. The status card moved into a shared monitor_status_card layout that both variants include. The Decodes entry is gone from the navigation menu and graph, leaving four destinations. --- .../layout-sw600dp-land/fragment_monitor.xml | 84 +++++++ .../src/main/res/layout/fragment_monitor.xml | 217 ++---------------- .../main/res/layout/monitor_status_card.xml | 183 +++++++++++++++ .../app/src/main/res/menu/bottom_nav_menu.xml | 5 - .../main/res/navigation/mobile_navigation.xml | 5 - 5 files changed, 287 insertions(+), 207 deletions(-) create mode 100644 android/app/src/main/res/layout-sw600dp-land/fragment_monitor.xml create mode 100644 android/app/src/main/res/layout/monitor_status_card.xml diff --git a/android/app/src/main/res/layout-sw600dp-land/fragment_monitor.xml b/android/app/src/main/res/layout-sw600dp-land/fragment_monitor.xml new file mode 100644 index 000000000..e4f1d66bd --- /dev/null +++ b/android/app/src/main/res/layout-sw600dp-land/fragment_monitor.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/layout/fragment_monitor.xml b/android/app/src/main/res/layout/fragment_monitor.xml index 6e9492b9b..a60752f80 100644 --- a/android/app/src/main/res/layout/fragment_monitor.xml +++ b/android/app/src/main/res/layout/fragment_monitor.xml @@ -1,219 +1,42 @@ - + android:layout_height="match_parent" + android:orientation="vertical"> + android:layout_weight="1.1" + android:background="@color/waterfall_background" /> - + android:layout_margin="8dp" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -