Skip to content

Commit

Permalink
Update Catalog dark theme toggle to be a menu with System default option
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 246841272
  • Loading branch information
dsn5ft committed May 6, 2019
1 parent 8f62228 commit 9f692ec
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@
-->
<resources>

<item name="cat_toc_dark_theme_toggle" type="id"/>
<item name="cat_toc_theme_button" type="id"/>

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@
<item name="navigationIcon">@drawable/ic_close_vd_theme_24px</item>
</style>

<style name="Widget.Catalog.ImageButton.DarkThemeToggle" parent="Widget.AppCompat.ImageButton">
<item name="android:id">@id/cat_toc_dark_theme_toggle</item>
<style name="Widget.Catalog.ChooseThemeButton" parent="Widget.AppCompat.ImageButton">
<item name="android:id">@id/cat_toc_theme_button</item>
<item name="android:layout_width">@dimen/mtrl_min_touch_target_size</item>
<item name="android:layout_height">@dimen/mtrl_min_touch_target_size</item>
<item name="android:layout_gravity">center_vertical|end</item>
<item name="android:background">?attr/actionBarItemBackground</item>
<item name="srcCompat">@drawable/abc_ic_menu_overflow_material</item>
</style>

<style name="ThemeOverlay.Catalog.AppBarLayout" parent="">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!--
Copyright 2019 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
https://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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M6,18c0,0.55 0.45,1 1,1h1v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L11,19h2v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L16,19h1c0.55,0 1,-0.45 1,-1L18,8L6,8v10zM3.5,8C2.67,8 2,8.67 2,9.5v7c0,0.83 0.67,1.5 1.5,1.5S5,17.33 5,16.5v-7C5,8.67 4.33,8 3.5,8zM20.5,8c-0.83,0 -1.5,0.67 -1.5,1.5v7c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5v-7c0,-0.83 -0.67,-1.5 -1.5,-1.5zM15.53,2.16l1.3,-1.3c0.2,-0.2 0.2,-0.51 0,-0.71 -0.2,-0.2 -0.51,-0.2 -0.71,0l-1.48,1.48C13.85,1.23 12.95,1 12,1c-0.96,0 -1.86,0.23 -2.66,0.63L7.85,0.15c-0.2,-0.2 -0.51,-0.2 -0.71,0 -0.2,0.2 -0.2,0.51 0,0.71l1.31,1.31C6.97,3.26 6,5.01 6,7h12c0,-1.99 -0.97,-3.75 -2.47,-4.84zM10,5L9,5L9,4h1v1zM15,5h-1L14,4h1v1z"/>
</vector>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright 2019 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.
*/

package io.material.catalog.tableofcontents;

import io.material.catalog.R;

import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.IdRes;
import androidx.appcompat.app.AppCompatDelegate;
import android.util.SparseIntArray;

class ThemePreferencesRepository {

private static final String PREFERENCES_NAME = "night_mode_preferences";
private static final String KEY_NIGHT_MODE = "night_mode";
private static final SparseIntArray THEME_NIGHT_MODE_MAP = new SparseIntArray();

static {
THEME_NIGHT_MODE_MAP.append(R.id.theme_light, AppCompatDelegate.MODE_NIGHT_NO);
THEME_NIGHT_MODE_MAP.append(R.id.theme_dark, AppCompatDelegate.MODE_NIGHT_YES);
THEME_NIGHT_MODE_MAP.append(R.id.theme_default, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
}

private final Context context;

ThemePreferencesRepository(Context context) {
this.context = context;
}

void saveAndApplyTheme(@IdRes int id) {
int nightMode = convertToNightMode(id);
saveNightMode(nightMode);
AppCompatDelegate.setDefaultNightMode(nightMode);
}

void applyTheme() {
ensureDefaultNightMode(getNightMode());
}

private void ensureDefaultNightMode(int mode) {
if (AppCompatDelegate.getDefaultNightMode() != mode) {
AppCompatDelegate.setDefaultNightMode(mode);
}
}

private int getNightMode() {
return getSharedPreferences()
.getInt(KEY_NIGHT_MODE, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
}

private void saveNightMode(int nightMode) {
getSharedPreferences().edit().putInt(KEY_NIGHT_MODE, nightMode).commit();
}

private SharedPreferences getSharedPreferences() {
return context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
}

private int convertToNightMode(@IdRes int id) {
return THEME_NIGHT_MODE_MAP.get(id, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
}
}
51 changes: 22 additions & 29 deletions catalog/java/io/material/catalog/tableofcontents/TocFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@
import androidx.core.content.ContextCompat;
import androidx.core.math.MathUtils;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.view.menu.MenuBuilder;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.appcompat.widget.PopupMenu;
import androidx.recyclerview.widget.RecyclerView;
import androidx.appcompat.widget.Toolbar;
import android.util.DisplayMetrics;
Expand All @@ -56,17 +57,17 @@ public class TocFragment extends DaggerFragment {
@Inject Set<FeatureDemo> featureDemos;
@Inject TocResourceProvider tocResourceProvider;

private DarkThemePreferencesRepository darkThemePreferencesRepository;
private ThemePreferencesRepository themePreferencesRepository;
private AppBarLayout appBarLayout;
private View gridTopDivider;
private RecyclerView recyclerView;
private ImageButton darkThemeToggle;
private ImageButton themeButton;

@Override
public void onCreate(@Nullable Bundle bundle) {
super.onCreate(bundle);

darkThemePreferencesRepository = new DarkThemePreferencesRepository(getContext());
themePreferencesRepository = new ThemePreferencesRepository(getContext());

String defaultDemo = FeatureDemoUtils.getDefaultDemo(getContext());
if (!defaultDemo.isEmpty() && bundle == null) {
Expand Down Expand Up @@ -99,7 +100,7 @@ public View onCreateView(
appBarLayout = view.findViewById(R.id.cat_toc_app_bar_layout);
gridTopDivider = view.findViewById(R.id.cat_toc_grid_top_divider);
recyclerView = view.findViewById(R.id.cat_toc_grid);
darkThemeToggle = view.findViewById(R.id.cat_toc_dark_theme_toggle);
themeButton = view.findViewById(R.id.cat_toc_theme_button);

if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
addGridTopDividerVisibilityListener();
Expand Down Expand Up @@ -129,7 +130,7 @@ public View onCreateView(
TocAdapter tocAdapter = new TocAdapter(getActivity(), featureList);
recyclerView.setAdapter(tocAdapter);

initDarkThemeToggle();
initThemeButton();

return view;
}
Expand Down Expand Up @@ -165,31 +166,23 @@ private int calculateGridSpanCount() {
return MathUtils.clamp(gridSpanCount, GRID_SPAN_COUNT_MIN, GRID_SPAN_COUNT_MAX);
}

private void initDarkThemeToggle() {
boolean darkThemeEnabled = darkThemePreferencesRepository.isDarkThemeEnabled();
darkThemeToggle.setImageResource(
darkThemeEnabled
? R.drawable.ic_night_on_vd_theme_24px
: R.drawable.ic_night_off_vd_theme_24px);
ensureDefaultNightMode(convertToNightMode(darkThemeEnabled));
darkThemeToggle.setOnClickListener(v -> toggleNightMode());
private void initThemeButton() {
themePreferencesRepository.applyTheme();
themeButton.setOnClickListener(v -> showThemePopup());
}

private void ensureDefaultNightMode(int mode) {
if (AppCompatDelegate.getDefaultNightMode() != mode) {
AppCompatDelegate.setDefaultNightMode(mode);
@SuppressWarnings("RestrictTo")
private void showThemePopup() {
PopupMenu popupMenu = new PopupMenu(getContext(), themeButton);
popupMenu.inflate(R.menu.theme_menu);
if (popupMenu.getMenu() instanceof MenuBuilder) {
((MenuBuilder) popupMenu.getMenu()).setOptionalIconsVisible(true);
}
}

private void toggleNightMode() {
boolean newDarkThemeEnabled = !darkThemePreferencesRepository.isDarkThemeEnabled();
darkThemePreferencesRepository.saveDarkThemeEnabled(newDarkThemeEnabled);
AppCompatDelegate.setDefaultNightMode(convertToNightMode(newDarkThemeEnabled));
}

private int convertToNightMode(boolean darkThemeEnabled) {
return darkThemeEnabled
? AppCompatDelegate.MODE_NIGHT_YES
: AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
popupMenu.setOnMenuItemClickListener(
item -> {
themePreferencesRepository.saveAndApplyTheme(item.getItemId());
return false;
});
popupMenu.show();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item
android:drawable="@drawable/ic_night_on_vd_theme_24px"
android:drawable="@drawable/ic_theme_dark_vd_theme_24px"
android:state_selected="true"/>

<item
android:drawable="@drawable/ic_night_off_vd_theme_24px"/>
android:drawable="@drawable/ic_theme_light_vd_theme_24px"/>

</selector>
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@
</LinearLayout>

<ImageButton
style="@style/Widget.Catalog.ImageButton.DarkThemeToggle"/>
style="@style/Widget.Catalog.ChooseThemeButton"/>
</FrameLayout>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 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.
-->

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item
android:id="@+id/theme_light"
android:icon="@drawable/ic_theme_light_vd_theme_24px"
android:title="@string/cat_choose_theme_light"/>

<item
android:id="@+id/theme_dark"
android:icon="@drawable/ic_theme_dark_vd_theme_24px"
android:title="@string/cat_choose_theme_dark"/>

<item
android:id="@+id/theme_default"
android:icon="@drawable/ic_theme_default_vd_theme_24px"
android:title="@string/cat_choose_theme_default"/>

</menu>
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

<resources>
<string name="cat_toc_title">Material Components</string>

<string name="cat_toc_status_wip">WIP</string>
<string name="cat_choose_theme_light">Light theme</string>
<string name="cat_choose_theme_dark">Dark theme</string>
<string name="cat_choose_theme_default">System default</string>
</resources>

0 comments on commit 9f692ec

Please sign in to comment.