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 |