diff options
-rwxr-xr-x | AndroidManifest.xml | 4 | ||||
-rw-r--r-- | res/color/bottom_nav_item_color.xml | 24 | ||||
-rw-r--r-- | res/drawable/ic_nav_theme.xml | 13 | ||||
-rwxr-xr-x | res/layout/activity_customization_picker_main.xml | 37 | ||||
-rw-r--r-- | res/menu/bottom_navigation_menu.xml | 35 | ||||
-rw-r--r-- | res/values/colors.xml | 23 | ||||
-rwxr-xr-x | res/values/strings.xml | 15 | ||||
-rw-r--r-- | res/values/styles.xml | 44 | ||||
-rw-r--r-- | src/com/android/customization/picker/CustomizationPickerActivity.java | 131 |
9 files changed, 318 insertions, 8 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7610e133..da3d15ef 100755 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -8,14 +8,14 @@ android:hardwareAccelerated="true" android:icon="@mipmap/product_logo_wallpapers_launcher_color_48" android:label="@string/app_name" - android:theme="@style/WallpaperTheme" + android:theme="@style/CustomizationTheme" android:requiredForAllUsers="true" android:restoreAnyVersion="true" android:supportsRtl="true"> <activity android:name="com.android.theme.picker.ThemePickerActivity" android:label="@string/app_name" - android:theme="@style/WallpaperTheme" + android:theme="@style/CustomizationTheme.NoActionBar" android:resizeableActivity="true"> <intent-filter> <action android:name="android.intent.action.SET_WALLPAPER"/> diff --git a/res/color/bottom_nav_item_color.xml b/res/color/bottom_nav_item_color.xml new file mode 100644 index 00000000..d1c118bf --- /dev/null +++ b/res/color/bottom_nav_item_color.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 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. +--> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:state_checked="true" + android:color="@color/accent_color" /> + <item + android:state_checked="false" + android:color="@color/material_grey500" /> +</selector>
\ No newline at end of file diff --git a/res/drawable/ic_nav_theme.xml b/res/drawable/ic_nav_theme.xml new file mode 100644 index 00000000..52e3961e --- /dev/null +++ b/res/drawable/ic_nav_theme.xml @@ -0,0 +1,13 @@ +<!-- TODO (santie): replace with correct asset once available --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10s10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8s8,3.59 8,8C20,16.41 16.41,20 12,20z"/> + <path + android:fillColor="#FF000000" + android:pathData="M6.5,17.5l7.51,-3.49L17.5,6.5L9.99,9.99L6.5,17.5zM12,10.9c0.61,0 1.1,0.49 1.1,1.1s-0.49,1.1 -1.1,1.1s-1.1,-0.49 -1.1,-1.1S11.39,10.9 12,10.9z"/> +</vector> diff --git a/res/layout/activity_customization_picker_main.xml b/res/layout/activity_customization_picker_main.xml new file mode 100755 index 00000000..40fcabb5 --- /dev/null +++ b/res/layout/activity_customization_picker_main.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 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. +--> +<androidx.coordinatorlayout.widget.CoordinatorLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <FrameLayout + android:id="@+id/fragment_container" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <com.google.android.material.bottomnavigation.BottomNavigationView + style="@style/BottomNavStyle" + android:id="@+id/main_bottom_nav" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + app:labelVisibilityMode="labeled" + app:menu="@menu/bottom_navigation_menu"/> +</androidx.coordinatorlayout.widget.CoordinatorLayout> diff --git a/res/menu/bottom_navigation_menu.xml b/res/menu/bottom_navigation_menu.xml new file mode 100644 index 00000000..49542064 --- /dev/null +++ b/res/menu/bottom_navigation_menu.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 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"> + <!-- TODO (santie): replace icons with real ones when available --> + <item + android:id="@+id/nav_theme" + android:title="@string/theme_title" + android:icon="@drawable/ic_nav_theme" /> + <item + android:id="@+id/nav_clock" + android:title="@string/clock_title" + android:icon="@drawable/ic_nav_theme" /> + <item + android:id="@+id/nav_grid" + android:title="@string/grid_title" + android:icon="@drawable/ic_nav_theme" /> + <item + android:id="@+id/nav_wallpaper" + android:title="@string/wallpaper_title" + android:icon="@drawable/ic_nav_theme" /> +</menu>
\ No newline at end of file diff --git a/res/values/colors.xml b/res/values/colors.xml new file mode 100644 index 00000000..2bdd26a9 --- /dev/null +++ b/res/values/colors.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + + Copyright (C) 2018 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. +--> +<resources> + <color name="status_bar_color">#ffffffff</color> + + <color name="system_navigation_bar_background">@android:color/white</color> + <color name="system_navigation_bar_divider">#1f000000</color> +</resources>
\ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index a57fd07f..f04ee7e2 100755 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -18,4 +18,19 @@ <!-- The name of this application, a theme picker. [CHAR LIMIT=50] --> <string name="app_name">Themes & Styles</string> + <!-- Title of a section of the customization picker where the user can select a Theme for the + device. [CHAR LIMIT=15] --> + <string name="theme_title">Theme</string> + + <!-- Title of a section of the customization picker where the user can select a Clock face. + [CHAR LIMIT=15] --> + <string name="clock_title">Clock</string> + + <!-- Title of a section of the customization picker where the user can select a Grid size for + the home screen. [CHAR LIMIT=15] --> + <string name="grid_title">Grid</string> + + <!-- Title of a section of the customization picker where the user can select a Wallpaper. + [CHAR LIMIT=15] --> + <string name="wallpaper_title">Wallpaper</string> </resources> diff --git a/res/values/styles.xml b/res/values/styles.xml new file mode 100644 index 00000000..dcc76e57 --- /dev/null +++ b/res/values/styles.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2018 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. +--> +<resources> + <style name="CustomizationTheme" parent="@android:style/Theme.DeviceDefault.Settings"> + <item name="colorPrimary">?android:colorPrimary</item> + + <item name="android:statusBarColor">@android:color/white</item> + <item name="android:windowLightStatusBar">true</item> + + <item name="android:navigationBarColor">@color/system_navigation_bar_background</item> + <item name="android:navigationBarDividerColor">@color/system_navigation_bar_divider</item> + <item name="android:windowLightNavigationBar">true</item> + + <item name="selectableItemBackground">?android:attr/selectableItemBackground</item> + </style> + <style name="CustomizationTheme.NoActionBar"> + <item name="android:windowActionBar">false</item> + <item name="android:windowNoTitle">true</item> + </style> + <style name="BottomNavStyle" parent="@style/Widget.MaterialComponents.BottomNavigationView"> + <item name="itemIconTint">@color/bottom_nav_item_color</item> + <item name="itemTextColor">@color/bottom_nav_item_color</item> + <item name="itemTextAppearanceActive">@style/BottomNavTextAppearance</item> + <item name="itemTextAppearanceInactive">@style/BottomNavTextAppearance</item> + </style> + + <style name="BottomNavTextAppearance" parent="@android:style/TextAppearance.Small"> + <item name="android:textStyle">bold</item> + </style> +</resources>
\ No newline at end of file diff --git a/src/com/android/customization/picker/CustomizationPickerActivity.java b/src/com/android/customization/picker/CustomizationPickerActivity.java index c4828266..2eb0c937 100644 --- a/src/com/android/customization/picker/CustomizationPickerActivity.java +++ b/src/com/android/customization/picker/CustomizationPickerActivity.java @@ -18,15 +18,23 @@ package com.android.customization.picker; import android.content.Intent; import android.os.Bundle; import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import androidx.annotation.IdRes; import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentTransaction; +import com.android.wallpaper.R; import com.android.wallpaper.model.WallpaperInfo; +import com.android.wallpaper.module.DailyLoggingAlarmScheduler; import com.android.wallpaper.module.FormFactorChecker; import com.android.wallpaper.module.Injector; import com.android.wallpaper.module.InjectorProvider; import com.android.wallpaper.module.UserEventLogger; -import com.android.wallpaper.picker.BaseActivity; import com.android.wallpaper.picker.CategoryFragment; import com.android.wallpaper.picker.CategoryFragment.CategoryFragmentHost; import com.android.wallpaper.picker.MyPhotosLauncher.PermissionChangedListener; @@ -34,14 +42,26 @@ import com.android.wallpaper.picker.TopLevelPickerActivity; import com.android.wallpaper.picker.WallpaperPickerDelegate; import com.android.wallpaper.picker.WallpapersUiContainer; -//TODO(santie): implement -public class CustomizationPickerActivity extends BaseActivity implements WallpapersUiContainer, +import com.google.android.material.bottomnavigation.BottomNavigationView; + +import java.util.HashMap; +import java.util.Map; + +/** + * Main Activity allowing containing a bottom nav bar for the user to switch between the different + * Fragments providing customization options. + */ +public class CustomizationPickerActivity extends FragmentActivity implements WallpapersUiContainer, CategoryFragmentHost { private static final String TAG = "CustomizationPickerActivity"; private WallpaperPickerDelegate mDelegate; private UserEventLogger mUserEventLogger; + private BottomNavigationView mBottomNav; + + private static final Map<Integer, CustomizationSection> mSections = new HashMap<>(); + private CategoryFragment mWallpaperCategoryFragment; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -50,19 +70,77 @@ public class CustomizationPickerActivity extends BaseActivity implements Wallpap mDelegate = new WallpaperPickerDelegate(this, this, injector); mUserEventLogger = injector.getUserEventLogger(this); + initSections(); + if (!supportsCustomization()) { Log.w(TAG, "Themes not supported, reverting to Wallpaper Picker"); Intent intent = new Intent(this, TopLevelPickerActivity.class); startActivity(intent); finish(); } + + setContentView(R.layout.activity_customization_picker_main); + setUpBottomNavView(); + + FragmentManager fm = getSupportFragmentManager(); + Fragment fragment = fm.findFragmentById(R.id.fragment_container); + + boolean forceCategoryRefresh = false; + if (fragment == null) { + // App launch specific logic: log the "app launched" event and set up daily logging. + mUserEventLogger.logAppLaunched(); + DailyLoggingAlarmScheduler.setAlarm(getApplicationContext()); + navigateToSection(R.id.nav_wallpaper); + forceCategoryRefresh = true; + } + + mDelegate.initialize(forceCategoryRefresh); + } private boolean supportsCustomization() { - // TODO (santie): check for actual themes support - return mDelegate.getFormFactor() == FormFactorChecker.FORM_FACTOR_MOBILE; + //TODO (santie): the check for sections.size() should be > 1: if we only have wallpaper we + // should default to the Wallpaper only UI + return mDelegate.getFormFactor() == FormFactorChecker.FORM_FACTOR_MOBILE + && mSections.size() > 0; } + private void initSections() { + mSections.put(R.id.nav_wallpaper, new WallpaperSection(R.id.nav_wallpaper)); + //TODO (santie): add other sections if supported by the device + } + + private void setUpBottomNavView() { + mBottomNav = findViewById(R.id.main_bottom_nav); + Menu menu = mBottomNav.getMenu(); + for (int i = menu.size() - 1; i >= 0; i--) { + MenuItem item = menu.getItem(i); + if (!mSections.containsKey(item.getItemId())) { + menu.removeItem(item.getItemId()); + } + } + + mBottomNav.setOnNavigationItemSelectedListener(item -> { + switchFragment(item.getItemId()); + return true; + }); + } + + private void navigateToSection(@IdRes int id) { + mBottomNav.setSelectedItemId(id); + } + + private void switchFragment(int id) { + final FragmentManager fragmentManager = getSupportFragmentManager(); + + Fragment fragment = mSections.get(id).getFragment(); + + final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + fragmentTransaction.replace(R.id.fragment_container, fragment); + fragmentTransaction.commitNow(); + } + + @Override public void requestExternalStoragePermission(PermissionChangedListener listener) { @@ -94,11 +172,52 @@ public class CustomizationPickerActivity extends BaseActivity implements Wallpap @Nullable @Override public CategoryFragment getCategoryFragment() { - return null; + return mWallpaperCategoryFragment; } @Override public void doneFetchingCategories() { } + + /** + * Represents a section of the Picker (eg "Theme", "Clock", etc). + * There should be a concrete subclass per available section, providing the corresponding + * Fragment to be displayed when switching to each section. + */ + static abstract class CustomizationSection { + + /** + * IdRes used to identify this section in the BottomNavigationView menu. + */ + @IdRes final int id; + + private CustomizationSection(@IdRes int id) { + this.id = id; + } + + /** + * @return the Fragment corresponding to this section. + */ + abstract Fragment getFragment(); + + } + + /** + * {@link CustomizationSection} corresponding to the "Wallpaper" section of the Picker. + */ + private class WallpaperSection extends CustomizationSection { + + private WallpaperSection(int id) { + super(id); + } + + @Override + Fragment getFragment() { + if (mWallpaperCategoryFragment == null) { + mWallpaperCategoryFragment = new CategoryFragment(); + } + return mWallpaperCategoryFragment; + } + } } |