summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael W <baddaemon87@gmail.com>2020-06-07 14:12:38 +0200
committerMichael Bestas <mkbestas@lineageos.org>2020-12-08 19:39:12 +0200
commit248c6793c4892b8444d64e89c221533270b2946a (patch)
tree72ede7dc1bd3a42f0ac4d86160eb740a52a88600
parent7829e74d9028bda24f05ff93ca5b14ef9b9a0dba (diff)
DeskClock: Move navigation bar to bottom
* Wrap the desk_clock layout into a LinearLayout so the Snackbar appears above the BottomNavigationView * Change the icon tint and text color to reflect the changes for the dark layout * Use a BottomNavigationView instead of a TabLayout * Reorder imports - looks like someone didn't care before Co-authored-by: Arian <arian.kulmer@web.de> Co-authored-by: Jesse Chan <jc@lineageos.org> Signed-off-by: Jesse Chan <jc@lineageos.org> Change-Id: I780713dcbeb58256b2660a9631d48e5f7259fb11
-rw-r--r--res/color/tab_tint_color.xml8
-rw-r--r--res/layout/desk_clock.xml161
-rw-r--r--res/layout/tab_item.xml26
-rw-r--r--res/menu/bottom_navigation_menu.xml23
-rw-r--r--res/values-night/colors.xml1
-rw-r--r--res/values/colors.xml2
-rw-r--r--res/values/styles.xml4
-rw-r--r--src/com/android/deskclock/DeskClock.java130
-rw-r--r--src/com/android/deskclock/uidata/UiDataModel.java18
9 files changed, 170 insertions, 203 deletions
diff --git a/res/color/tab_tint_color.xml b/res/color/tab_tint_color.xml
index 912a9fe6a..3814e506f 100644
--- a/res/color/tab_tint_color.xml
+++ b/res/color/tab_tint_color.xml
@@ -15,7 +15,7 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_focused="true" android:color="@color/white" />
- <item android:state_selected="true" android:color="@color/white" />
- <item android:color="@color/white_63p" />
-</selector> \ No newline at end of file
+ <item android:state_focused="true" android:color="@color/accent_color" />
+ <item android:state_selected="true" android:color="@color/accent_color" />
+ <item android:color="@color/white_50p" />
+</selector>
diff --git a/res/layout/desk_clock.xml b/res/layout/desk_clock.xml
index d25e4f628..76ea224c3 100644
--- a/res/layout/desk_clock.xml
+++ b/res/layout/desk_clock.xml
@@ -15,117 +15,118 @@
limitations under the License.
-->
-<androidx.coordinatorlayout.widget.CoordinatorLayout
+<LinearLayout
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:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:fitsSystemWindows="true"
- app:statusBarBackground="@null">
+ android:orientation="vertical"
+ app:statusBarBackground="@null"
+ android:fitsSystemWindows="true">
- <com.google.android.material.appbar.AppBarLayout
+ <androidx.coordinatorlayout.widget.CoordinatorLayout
+ android:id="@+id/content"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@null"
- app:elevation="0dp">
+ android:layout_height="0dp"
+ android:layout_weight="1">
- <androidx.appcompat.widget.Toolbar
- android:id="@+id/toolbar"
+ <com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- app:contentInsetStart="0dp"
- tools:ignore="RtlSymmetry">
+ android:background="@null"
+ app:elevation="0dp">
- <com.google.android.material.tabs.TabLayout
- android:id="@+id/tabs"
+ <androidx.appcompat.widget.Toolbar
+ android:id="@+id/toolbar"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- app:tabGravity="fill"
- app:tabIndicatorColor="@android:color/transparent"
- app:tabMaxWidth="0dp"
- app:tabMode="fixed"
- app:tabPaddingEnd="0dp"
- app:tabPaddingStart="0dp" />
-
- </androidx.appcompat.widget.Toolbar>
-
- <View
- android:id="@+id/tab_hairline"
- android:layout_width="match_parent"
- android:layout_height="@dimen/hairline_height"
- android:layout_gravity="bottom"
- android:background="@color/hairline"
- android:importantForAccessibility="no" />
+ android:layout_height="wrap_content"
+ app:contentInsetStart="0dp"
+ tools:ignore="RtlSymmetry"
+ android:gravity="center">
- </com.google.android.material.appbar.AppBarLayout>
+ <TextView
+ android:id="@+id/title_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title" />
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- app:layout_behavior="@string/appbar_scrolling_view_behavior">
+ </androidx.appcompat.widget.Toolbar>
+ </com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/desk_clock_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAccessibility="no"
- android:saveEnabled="false" />
+ android:saveEnabled="false"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior" />
- <include layout="@layout/drop_shadow" />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:baselineAligned="false"
+ android:orientation="horizontal"
+ app:layout_behavior="com.android.deskclock.widget.toast.SnackbarSlidingBehavior">
- </FrameLayout>
+ <FrameLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="start|center_vertical"
+ android:layout_weight="1">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:baselineAligned="false"
- android:orientation="horizontal"
- app:layout_behavior="com.android.deskclock.widget.toast.SnackbarSlidingBehavior">
+ <Button
+ android:id="@+id/left_button"
+ style="?attr/borderlessButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:scaleType="centerInside" />
- <FrameLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_gravity="start|center_vertical"
- android:layout_weight="1">
+ </FrameLayout>
- <Button
- android:id="@+id/left_button"
- style="?attr/borderlessButtonStyle"
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
+ android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:scaleType="centerInside" />
+ android:layout_margin="@dimen/fab_margin"
+ app:borderWidth="0dp"
+ app:elevation="@dimen/fab_elevation" />
- </FrameLayout>
+ <FrameLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="end|center_vertical"
+ android:layout_weight="1">
- <com.google.android.material.floatingactionbutton.FloatingActionButton
- android:id="@+id/fab"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_margin="@dimen/fab_margin"
- app:borderWidth="0dp"
- app:elevation="@dimen/fab_elevation" />
+ <Button
+ android:id="@+id/right_button"
+ style="?attr/borderlessButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:scaleType="centerInside" />
- <FrameLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_gravity="end|center_vertical"
- android:layout_weight="1">
+ </FrameLayout>
- <Button
- android:id="@+id/right_button"
- style="?attr/borderlessButtonStyle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:scaleType="centerInside" />
+ </LinearLayout>
- </FrameLayout>
+ </androidx.coordinatorlayout.widget.CoordinatorLayout>
- </LinearLayout>
-
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
+ <com.google.android.material.bottomnavigation.BottomNavigationView
+ android:id="@+id/bottom_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/content"
+ android:background="@color/secondary_color"
+ app:menu="@menu/bottom_navigation_menu"
+ app:itemIconTint="@color/tab_tint_color"
+ app:itemTextColor="@color/tab_tint_color"
+ app:itemTextAppearanceActive="@style/navText"
+ app:itemTextAppearanceInactive="@style/navText"
+ app:labelVisibilityMode="labeled" />
+
+</LinearLayout>
diff --git a/res/layout/tab_item.xml b/res/layout/tab_item.xml
deleted file mode 100644
index 4d8b17c19..000000000
--- a/res/layout/tab_item.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<TextView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@android:id/text1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawablePadding="10dp"
- android:gravity="center"
- android:includeFontPadding="false"
- android:singleLine="true"
- android:textAppearance="@style/TextAppearance.Tab" />
diff --git a/res/menu/bottom_navigation_menu.xml b/res/menu/bottom_navigation_menu.xml
new file mode 100644
index 000000000..1ad8469de
--- /dev/null
+++ b/res/menu/bottom_navigation_menu.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/page_alarm"
+ android:enabled="true"
+ android:icon="@drawable/ic_tab_alarm"
+ android:title="@string/menu_alarm"/>
+ <item
+ android:id="@+id/page_clock"
+ android:enabled="true"
+ android:icon="@drawable/ic_tab_clock"
+ android:title="@string/menu_clock"/>
+ <item
+ android:id="@+id/page_timer"
+ android:enabled="true"
+ android:icon="@drawable/ic_tab_timer"
+ android:title="@string/menu_timer"/>
+ <item
+ android:id="@+id/page_stopwatch"
+ android:enabled="true"
+ android:icon="@drawable/ic_tab_stopwatch"
+ android:title="@string/menu_stopwatch"/>
+</menu>
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index a555c4981..be5642398 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -18,4 +18,5 @@
<resources>
<color name="default_background">#121212</color>
<color name="accent_color">#FEF177</color>
+ <color name="secondary_color">#212121</color>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index a6a127480..519b470ba 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -24,6 +24,7 @@
<color name="white">#FFFFFFFF</color>
<color name="white_08p">#14FFFFFF</color>
<color name="white_63p">#A0FFFFFF</color>
+ <color name="white_50p">#80FFFFFF</color>
<color name="no_alarms">#4CFFFFFF</color>
<color name="transparent">#00000000</color>
@@ -38,4 +39,5 @@
<color name="widget_shadow_color">#000000</color>
<color name="accent_color">#FFEB40</color>
+ <color name="secondary_color">#2F378A</color>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index f247f655b..fbe62ae3a 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -98,8 +98,7 @@
<style name="SecondaryLabelTextAppearance" parent="SecondaryLabelTextParentAppearance" />
- <style name="TextAppearance.Tab" parent="TextAppearance.Design.Tab">
- <item name="android:fontFamily">sans-serif-medium</item>
+ <style name="navText">
<item name="android:textSize">12sp</item>
</style>
@@ -133,7 +132,6 @@
<item name="android:headerBackground">@android:color/transparent</item>
<item name="android:numbersBackgroundColor">@android:color/transparent</item>
<item name="android:numbersSelectorColor">?attr/colorAccent</item>
- <item name="android:numbersTextColor">?android:attr/textColorPrimary</item>
</style>
</resources>
diff --git a/src/com/android/deskclock/DeskClock.java b/src/com/android/deskclock/DeskClock.java
index 580e31201..cc3687002 100644
--- a/src/com/android/deskclock/DeskClock.java
+++ b/src/com/android/deskclock/DeskClock.java
@@ -32,6 +32,7 @@ import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
@@ -53,8 +54,8 @@ import com.android.deskclock.uidata.TabListener;
import com.android.deskclock.uidata.UiDataModel;
import com.android.deskclock.widget.toast.SnackbarManager;
+import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.snackbar.Snackbar;
-import com.google.android.material.tabs.TabLayout;
import static androidx.viewpager.widget.ViewPager.SCROLL_STATE_DRAGGING;
import static androidx.viewpager.widget.ViewPager.SCROLL_STATE_IDLE;
@@ -115,17 +116,17 @@ public class DeskClock extends BaseActivity
/** The button right of the {@link #mFab} shared across all tabs in the user interface. */
private Button mRightButton;
- /** The controller that shows the drop shadow when content is not scrolled to the top. */
- private DropShadowController mDropShadowController;
-
/** The ViewPager that pages through the fragments representing the content of the tabs. */
private ViewPager mFragmentTabPager;
/** Generates the fragments that are displayed by the {@link #mFragmentTabPager}. */
private FragmentTabPagerAdapter mFragmentTabPagerAdapter;
- /** The container that stores the tab headers. */
- private TabLayout mTabLayout;
+ /** The view that displays the current tab's title */
+ private TextView mTitleView;
+
+ /** The bottom navigation bar */
+ private BottomNavigationView mBottomNavigation;
/** {@code true} when a settings change necessitates recreating this activity. */
private boolean mRecreateActivity;
@@ -171,43 +172,6 @@ public class DeskClock extends BaseActivity
// inflation occurs *after* the initial draw and a second layout pass adds in the menu.
onCreateOptionsMenu(toolbar.getMenu());
- // Create the tabs that make up the user interface.
- mTabLayout = (TabLayout) findViewById(R.id.tabs);
- final int tabCount = UiDataModel.getUiDataModel().getTabCount();
- final boolean showTabLabel = getResources().getBoolean(R.bool.showTabLabel);
- final boolean showTabHorizontally = getResources().getBoolean(R.bool.showTabHorizontally);
- for (int i = 0; i < tabCount; i++) {
- final UiDataModel.Tab tabModel = UiDataModel.getUiDataModel().getTab(i);
- final @StringRes int labelResId = tabModel.getLabelResId();
-
- final TabLayout.Tab tab = mTabLayout.newTab()
- .setTag(tabModel)
- .setIcon(tabModel.getIconResId())
- .setContentDescription(labelResId);
-
- if (showTabLabel) {
- tab.setText(labelResId);
- tab.setCustomView(R.layout.tab_item);
-
- @SuppressWarnings("ConstantConditions")
- final TextView text = (TextView) tab.getCustomView()
- .findViewById(android.R.id.text1);
- text.setTextColor(mTabLayout.getTabTextColors());
-
- // Bind the icon to the TextView.
- final Drawable icon = tab.getIcon();
- if (showTabHorizontally) {
- // Remove the icon so it doesn't affect the minimum TabLayout height.
- tab.setIcon(null);
- text.setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null);
- } else {
- text.setCompoundDrawablesRelativeWithIntrinsicBounds(null, icon, null, null);
- }
- }
-
- mTabLayout.addTab(tab);
- }
-
// Configure the buttons shared by the tabs.
mFab = (ImageView) findViewById(R.id.fab);
mLeftButton = (Button) findViewById(R.id.left_button);
@@ -297,24 +261,47 @@ public class DeskClock extends BaseActivity
mFragmentTabPager.setAdapter(mFragmentTabPagerAdapter);
// Mirror changes made to the selected tab into UiDataModel.
- mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
- @Override
- public void onTabSelected(TabLayout.Tab tab) {
- UiDataModel.getUiDataModel().setSelectedTab((UiDataModel.Tab) tab.getTag());
- }
+ mBottomNavigation = findViewById(R.id.bottom_view);
+ mBottomNavigation.setOnNavigationItemSelectedListener(mNavigationListener);
- @Override
- public void onTabUnselected(TabLayout.Tab tab) {
+ // Honor changes to the selected tab from outside entities.
+ UiDataModel.getUiDataModel().addTabListener(mTabChangeWatcher);
+
+ mTitleView = findViewById(R.id.title_view);
+ }
+
+ private BottomNavigationView.OnNavigationItemSelectedListener mNavigationListener
+ = new BottomNavigationView.OnNavigationItemSelectedListener() {
+
+ @Override
+ public boolean onNavigationItemSelected(@NonNull MenuItem item) {
+ UiDataModel.Tab tab = null;
+ switch (item.getItemId()) {
+ case R.id.page_alarm:
+ tab = UiDataModel.Tab.ALARMS;
+ break;
+
+ case R.id.page_clock:
+ tab = UiDataModel.Tab.CLOCKS;
+ break;
+
+ case R.id.page_timer:
+ tab = UiDataModel.Tab.TIMERS;
+ break;
+
+ case R.id.page_stopwatch:
+ tab = UiDataModel.Tab.STOPWATCH;
+ break;
}
- @Override
- public void onTabReselected(TabLayout.Tab tab) {
+ if (tab != null) {
+ UiDataModel.getUiDataModel().setSelectedTab(tab);
+ return true;
}
- });
- // Honor changes to the selected tab from outside entities.
- UiDataModel.getUiDataModel().addTabListener(mTabChangeWatcher);
- }
+ return false;
+ }
+ };
@Override
protected void onStart() {
@@ -327,10 +314,6 @@ public class DeskClock extends BaseActivity
protected void onResume() {
super.onResume();
- final View dropShadow = findViewById(R.id.drop_shadow);
- mDropShadowController = new DropShadowController(dropShadow, UiDataModel.getUiDataModel(),
- mSnackbarAnchor.findViewById(R.id.tab_hairline));
-
// ViewPager does not save state; this honors the selected tab in the user interface.
updateCurrentTab();
}
@@ -354,16 +337,6 @@ public class DeskClock extends BaseActivity
}
@Override
- public void onPause() {
- if (mDropShadowController != null) {
- mDropShadowController.stop();
- mDropShadowController = null;
- }
-
- super.onPause();
- }
-
- @Override
protected void onStop() {
DataModel.getDataModel().removeSilentSettingsListener(mSilentSettingChangeWatcher);
if (!isChangingConfigurations()) {
@@ -487,21 +460,14 @@ public class DeskClock extends BaseActivity
}
/**
- * Configure the {@link #mFragmentTabPager} and {@link #mTabLayout} to display UiDataModel's
- * selected tab.
+ * Configure the {@link #mFragmentTabPager} and {@link #mBottomNavigation} to display
+ * UiDataModel's selected tab.
*/
private void updateCurrentTab() {
// Fetch the selected tab from the source of truth: UiDataModel.
final UiDataModel.Tab selectedTab = UiDataModel.getUiDataModel().getSelectedTab();
-
- // Update the selected tab in the tablayout if it does not agree with UiDataModel.
- for (int i = 0; i < mTabLayout.getTabCount(); i++) {
- final TabLayout.Tab tab = mTabLayout.getTabAt(i);
- if (tab != null && tab.getTag() == selectedTab && !tab.isSelected()) {
- tab.select();
- break;
- }
- }
+ // Update the selected tab in the mBottomNavigation if it does not agree with UiDataModel.
+ mBottomNavigation.setSelectedItemId(selectedTab.getPageResId());
// Update the selected fragment in the viewpager if it does not agree with UiDataModel.
for (int i = 0; i < mFragmentTabPagerAdapter.getCount(); i++) {
@@ -511,6 +477,8 @@ public class DeskClock extends BaseActivity
break;
}
}
+
+ mTitleView.setText(selectedTab.getLabelResId());
}
/**
diff --git a/src/com/android/deskclock/uidata/UiDataModel.java b/src/com/android/deskclock/uidata/UiDataModel.java
index f7a691756..3d592d405 100644
--- a/src/com/android/deskclock/uidata/UiDataModel.java
+++ b/src/com/android/deskclock/uidata/UiDataModel.java
@@ -19,7 +19,7 @@ package com.android.deskclock.uidata;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Typeface;
-import androidx.annotation.DrawableRes;
+import androidx.annotation.IntegerRes;
import androidx.annotation.StringRes;
import com.android.deskclock.AlarmClockFragment;
@@ -39,23 +39,23 @@ public final class UiDataModel {
/** Identifies each of the primary tabs within the application. */
public enum Tab {
- ALARMS(AlarmClockFragment.class, R.drawable.ic_tab_alarm, R.string.menu_alarm),
- CLOCKS(ClockFragment.class, R.drawable.ic_tab_clock, R.string.menu_clock),
- TIMERS(TimerFragment.class, R.drawable.ic_tab_timer, R.string.menu_timer),
- STOPWATCH(StopwatchFragment.class, R.drawable.ic_tab_stopwatch, R.string.menu_stopwatch);
+ ALARMS(AlarmClockFragment.class, R.id.page_alarm, R.string.menu_alarm),
+ CLOCKS(ClockFragment.class, R.id.page_clock, R.string.menu_clock),
+ TIMERS(TimerFragment.class, R.id.page_timer, R.string.menu_timer),
+ STOPWATCH(StopwatchFragment.class, R.id.page_stopwatch, R.string.menu_stopwatch);
private final String mFragmentClassName;
- private final @DrawableRes int mIconResId;
+ private final @IntegerRes int mPageResId;
private final @StringRes int mLabelResId;
- Tab(Class fragmentClass, @DrawableRes int iconResId, @StringRes int labelResId) {
+ Tab(Class fragmentClass, @IntegerRes int pageResId, @StringRes int labelResId) {
mFragmentClassName = fragmentClass.getName();
- mIconResId = iconResId;
+ mPageResId = pageResId;
mLabelResId = labelResId;
}
public String getFragmentClassName() { return mFragmentClassName; }
- public @DrawableRes int getIconResId() { return mIconResId; }
+ public @IntegerRes int getPageResId() { return mPageResId; }
public @StringRes int getLabelResId() { return mLabelResId; }
}