| OLD | NEW |
| (Empty) |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.chrome.browser.widget; | |
| 6 | |
| 7 import android.content.Context; | |
| 8 import android.content.res.Resources; | |
| 9 import android.support.design.internal.BottomNavigationItemView; | |
| 10 import android.support.design.internal.BottomNavigationMenuView; | |
| 11 import android.support.design.widget.BottomNavigationView; | |
| 12 import android.support.design.widget.BottomNavigationView.OnNavigationItemSelect
edListener; | |
| 13 import android.util.AttributeSet; | |
| 14 import android.view.MenuItem; | |
| 15 import android.view.View; | |
| 16 | |
| 17 import org.chromium.chrome.R; | |
| 18 import org.chromium.chrome.browser.bookmarks.BookmarkSheetContent; | |
| 19 import org.chromium.chrome.browser.download.DownloadSheetContent; | |
| 20 import org.chromium.chrome.browser.history.HistorySheetContent; | |
| 21 import org.chromium.chrome.browser.suggestions.SuggestionsBottomSheetContent; | |
| 22 import org.chromium.chrome.browser.tabmodel.TabModelSelector; | |
| 23 import org.chromium.chrome.browser.util.MathUtils; | |
| 24 import org.chromium.chrome.browser.widget.BottomSheet.BottomSheetContent; | |
| 25 | |
| 26 import java.lang.reflect.Field; | |
| 27 import java.util.HashMap; | |
| 28 import java.util.Iterator; | |
| 29 import java.util.Map; | |
| 30 import java.util.Map.Entry; | |
| 31 | |
| 32 /** | |
| 33 * Displays and controls a {@link BottomNavigationView} fixed to the bottom of t
he | |
| 34 * {@link BottomSheet}. Also manages {@link BottomSheetContent} displayed in the
BottomSheet. | |
| 35 */ | |
| 36 public class BottomSheetContentController extends BottomNavigationView | |
| 37 implements BottomSheetObserver, OnNavigationItemSelectedListener { | |
| 38 private BottomSheet mBottomSheet; | |
| 39 private TabModelSelector mTabModelSelector; | |
| 40 private float mDistanceBelowToolbarPx; | |
| 41 private int mSelectedItemId; | |
| 42 private boolean mDefaultContentInitialized; | |
| 43 | |
| 44 private final Map<Integer, BottomSheetContent> mBottomSheetContents = new Ha
shMap<>(); | |
| 45 | |
| 46 public BottomSheetContentController(Context context, AttributeSet atts) { | |
| 47 super(context, atts); | |
| 48 } | |
| 49 | |
| 50 /** | |
| 51 * Initializes the {@link BottomSheetContentController}. | |
| 52 * @param bottomSheet The {@link BottomSheet} associated with this bottom na
v. | |
| 53 * @param controlContainerHeight The height of the control container in px. | |
| 54 * @param tabModelSelector The {@link TabModelSelector} for the application. | |
| 55 */ | |
| 56 public void init(BottomSheet bottomSheet, int controlContainerHeight, | |
| 57 TabModelSelector tabModelSelector) { | |
| 58 mBottomSheet = bottomSheet; | |
| 59 mBottomSheet.addObserver(this); | |
| 60 mTabModelSelector = tabModelSelector; | |
| 61 | |
| 62 Resources res = getContext().getResources(); | |
| 63 mDistanceBelowToolbarPx = controlContainerHeight | |
| 64 + res.getDimensionPixelOffset(R.dimen.bottom_nav_space_from_tool
bar); | |
| 65 | |
| 66 setOnNavigationItemSelectedListener(this); | |
| 67 disableShiftingMode(); | |
| 68 } | |
| 69 | |
| 70 /** | |
| 71 * Initialize the default {@link BottomSheetContent}. | |
| 72 */ | |
| 73 public void initializeDefaultContent() { | |
| 74 if (mDefaultContentInitialized) return; | |
| 75 showBottomSheetContent(R.id.action_home); | |
| 76 mDefaultContentInitialized = true; | |
| 77 } | |
| 78 | |
| 79 @Override | |
| 80 public boolean onNavigationItemSelected(MenuItem item) { | |
| 81 if (mSelectedItemId == item.getItemId()) return false; | |
| 82 | |
| 83 showBottomSheetContent(item.getItemId()); | |
| 84 return true; | |
| 85 } | |
| 86 | |
| 87 @Override | |
| 88 public void onTransitionPeekToHalf(float transitionFraction) { | |
| 89 float offsetY = (mBottomSheet.getMinOffset() - mBottomSheet.getSheetOffs
etFromBottom()) | |
| 90 + mDistanceBelowToolbarPx; | |
| 91 setTranslationY((int) Math.max(offsetY, 0f)); | |
| 92 setVisibility(MathUtils.areFloatsEqual(transitionFraction, 0f) ? View.GO
NE : View.VISIBLE); | |
| 93 } | |
| 94 | |
| 95 @Override | |
| 96 public void onSheetOpened() { | |
| 97 if (!mDefaultContentInitialized && mTabModelSelector.getCurrentTab() !=
null) { | |
| 98 initializeDefaultContent(); | |
| 99 } | |
| 100 } | |
| 101 | |
| 102 @Override | |
| 103 public void onSheetClosed() { | |
| 104 Iterator<Entry<Integer, BottomSheetContent>> contentIterator = | |
| 105 mBottomSheetContents.entrySet().iterator(); | |
| 106 while (contentIterator.hasNext()) { | |
| 107 Entry<Integer, BottomSheetContent> entry = contentIterator.next(); | |
| 108 if (entry.getKey() == R.id.action_home) continue; | |
| 109 | |
| 110 entry.getValue().destroy(); | |
| 111 contentIterator.remove(); | |
| 112 } | |
| 113 // TODO(twellington): determine a policy for destroying the SuggestionsB
ottomSheetContent. | |
| 114 | |
| 115 if (mSelectedItemId == 0 || mSelectedItemId == R.id.action_home) return; | |
| 116 | |
| 117 showBottomSheetContent(R.id.action_home); | |
| 118 } | |
| 119 | |
| 120 @Override | |
| 121 public void onLoadUrl(String url) {} | |
| 122 | |
| 123 @Override | |
| 124 public void onSheetOffsetChanged(float heightFraction) {} | |
| 125 | |
| 126 // TODO(twellington): remove this once the support library is updated to all
ow disabling | |
| 127 // shifting mode or determines shifting mode based on the
width of the | |
| 128 // child views. | |
| 129 private void disableShiftingMode() { | |
| 130 BottomNavigationMenuView menuView = (BottomNavigationMenuView) getChildA
t(0); | |
| 131 try { | |
| 132 Field shiftingMode = menuView.getClass().getDeclaredField("mShifting
Mode"); | |
| 133 shiftingMode.setAccessible(true); | |
| 134 shiftingMode.setBoolean(menuView, false); | |
| 135 shiftingMode.setAccessible(false); | |
| 136 for (int i = 0; i < menuView.getChildCount(); i++) { | |
| 137 BottomNavigationItemView item = (BottomNavigationItemView) menuV
iew.getChildAt(i); | |
| 138 item.setShiftingMode(false); | |
| 139 // Set the checked value so that the view will be updated. | |
| 140 item.setChecked(item.getItemData().isChecked()); | |
| 141 } | |
| 142 } catch (NoSuchFieldException | IllegalAccessException e) { | |
| 143 // Do nothing if reflection fails. | |
| 144 } | |
| 145 } | |
| 146 | |
| 147 private BottomSheetContent getSheetContentForId(int navItemId) { | |
| 148 BottomSheetContent content = mBottomSheetContents.get(navItemId); | |
| 149 if (content != null) return content; | |
| 150 | |
| 151 if (navItemId == R.id.action_home) { | |
| 152 content = new SuggestionsBottomSheetContent( | |
| 153 mTabModelSelector.getCurrentTab().getActivity(), mBottomShee
t, | |
| 154 mTabModelSelector); | |
| 155 } else if (navItemId == R.id.action_downloads) { | |
| 156 content = new DownloadSheetContent(mTabModelSelector.getCurrentTab()
.getActivity(), | |
| 157 mTabModelSelector.getCurrentModel().isIncognito()); | |
| 158 } else if (navItemId == R.id.action_bookmarks) { | |
| 159 content = new BookmarkSheetContent(mTabModelSelector.getCurrentTab()
.getActivity()); | |
| 160 } else if (navItemId == R.id.action_history) { | |
| 161 content = new HistorySheetContent(mTabModelSelector.getCurrentTab().
getActivity()); | |
| 162 } | |
| 163 mBottomSheetContents.put(navItemId, content); | |
| 164 return content; | |
| 165 } | |
| 166 | |
| 167 private void showBottomSheetContent(int navItemId) { | |
| 168 // There are some bugs related to programatically selecting menu items t
hat are fixed in | |
| 169 // newer support library versions. | |
| 170 // TODO(twellington): remove this after the support library is rolled. | |
| 171 if (mSelectedItemId != 0) getMenu().findItem(mSelectedItemId).setChecked
(false); | |
| 172 mSelectedItemId = navItemId; | |
| 173 getMenu().findItem(mSelectedItemId).setChecked(true); | |
| 174 | |
| 175 mBottomSheet.showContent(getSheetContentForId(mSelectedItemId)); | |
| 176 } | |
| 177 } | |
| OLD | NEW |