Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java

Issue 2751333006: Create the base Custom Context Menu Dialog. (Closed)
Patch Set: git rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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.contextmenu;
6
7 import android.app.Dialog;
8 import android.content.Context;
9 import android.content.DialogInterface;
10 import android.support.design.widget.TabLayout;
11 import android.support.v4.view.ViewPager;
12 import android.support.v7.app.AlertDialog;
13 import android.text.TextUtils;
14 import android.util.Pair;
15 import android.view.LayoutInflater;
16 import android.view.View;
17 import android.view.ViewGroup;
18 import android.widget.AdapterView;
19 import android.widget.BaseAdapter;
20 import android.widget.ListView;
21 import android.widget.TextView;
22
23 import org.chromium.base.ApiCompatibilityUtils;
24 import org.chromium.base.Callback;
25 import org.chromium.base.VisibleForTesting;
26 import org.chromium.chrome.R;
27
28 import java.util.ArrayList;
29 import java.util.List;
30
31 /**
32 * A custom dialog that separates each group into separate tabs. It uses a dialo g instead.
33 */
34 public class TabularContextMenuUi implements ContextMenuUi, AdapterView.OnItemCl ickListener {
35 private Dialog mDialog;
36 private Callback<Integer> mCallback;
37 private int mMenuItemHeight;
38
39 @Override
40 public void displayMenu(Context context, ContextMenuParams params,
41 List<Pair<Integer, List<ContextMenuItem>>> items, Callback<Integer> onItemClicked,
42 final Runnable onMenuShown, final Runnable onMenuClosed) {
43 mCallback = onItemClicked;
44 mDialog = createDialog(context, params, items);
45 mDialog.getWindow().setBackgroundDrawable(ApiCompatibilityUtils.getDrawa ble(
46 context.getResources(), R.drawable.bg_find_toolbar_popup));
47
48 mDialog.setOnShowListener(new DialogInterface.OnShowListener() {
49 @Override
50 public void onShow(DialogInterface dialogInterface) {
51 onMenuShown.run();
52 }
53 });
54
55 mDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
56 @Override
57 public void onDismiss(DialogInterface dialogInterface) {
58 onMenuClosed.run();
59 }
60 });
61
62 mDialog.show();
63 }
64
65 /**
66 * Returns the fully complete dialog based off the params and the itemGroups .
67 * @param context Used to inflate the dialog.
68 * @param params Used to get the header title.
69 * @param itemGroups If there is more than one group it will create a paged view.
70 * @return Returns a final dialog that does not have a background can be dis played using
71 * {@link AlertDialog#show()}.
72 */
73 private Dialog createDialog(Context context, ContextMenuParams params,
74 List<Pair<Integer, List<ContextMenuItem>>> itemGroups) {
75 Dialog dialog = new Dialog(context);
76 dialog.setContentView(createPagerView(context, params, itemGroups));
77 return dialog;
78 }
79
80 /**
81 * Creates the view of a context menu. Based off the Context Type, it'll adj ust the list of
82 * items and display only the ones that'll be on that specific group.
83 * @param context Used to get the resources of an item.
84 * @param params used to create the header text.
85 * @param items A set of Items to display in a context menu. Filtered based off the type.
86 * @return Returns a filled LinearLayout with all the context menu items
87 */
88 @VisibleForTesting
89 ViewGroup createContextMenuPageUi(
90 Context context, ContextMenuParams params, List<ContextMenuItem> ite ms, int maxCount) {
91 ViewGroup baseLayout = (ViewGroup) LayoutInflater.from(context).inflate(
92 R.layout.tabular_context_menu_page, null);
93 ListView listView = (ListView) baseLayout.findViewById(R.id.selectable_i tems);
94 displayHeaderIfVisibleItems(params, baseLayout);
95
96 // Set the list adapter and get the height to display it appropriately i n a dialog.
97 TabularContextMenuListAdapter listAdapter =
98 new TabularContextMenuListAdapter(items, context);
99 ViewGroup.LayoutParams layoutParams = listView.getLayoutParams();
100 layoutParams.height = measureApproximateListViewHeight(listView, listAda pter, maxCount);
101 listView.setLayoutParams(layoutParams);
102 listView.setAdapter(listAdapter);
103 listView.setOnItemClickListener(this);
104
105 return baseLayout;
106 }
107
108 private void displayHeaderIfVisibleItems(ContextMenuParams params, ViewGroup baseLayout) {
109 String headerText = ChromeContextMenuPopulator.createHeaderText(params);
110 TextView headerTextView = (TextView) baseLayout.findViewById(R.id.contex t_header_text);
111 if (TextUtils.isEmpty(headerText)) {
112 headerTextView.setVisibility(View.GONE);
113 baseLayout.findViewById(R.id.context_divider).setVisibility(View.GON E);
114 return;
115 }
116 headerTextView.setVisibility(View.VISIBLE);
117 headerTextView.setText(headerText);
118 }
119
120 /**
121 * To save time measuring the height, this method gets an item if the height has not been
122 * previous measured and multiplies it by count of the total amount of items . It is fine if the
123 * height too small as the ListView will scroll through the other values.
124 * @param listView The ListView to measure the surrounding padding.
125 * @param listAdapter The adapter which contains the items within the list.
126 * @return Returns the combined height of the padding of the ListView and th e approximate height
127 * of the ListView based off the an item.
128 */
129 private int measureApproximateListViewHeight(
130 ListView listView, BaseAdapter listAdapter, int maxCount) {
131 int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom() ;
132 if (mMenuItemHeight == 0 && !listAdapter.isEmpty()) {
133 View view = listAdapter.getView(0, null, listView);
134 view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UN SPECIFIED),
135 View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECI FIED));
136 mMenuItemHeight = view.getMeasuredHeight();
137 }
138 return totalHeight + mMenuItemHeight * maxCount;
139 }
140
141 /**
142 * Creates a ViewPageAdapter based off the given list of views.
143 * @param context Used to inflate the new ViewPager
144 * @param params Used to get the header text.
145 * @param itemGroups The list of views to put into the ViewPager. The string is the title of the
146 * tab
147 * @return Returns a complete tabular context menu view.
148 */
149 @VisibleForTesting
150 View createPagerView(Context context, ContextMenuParams params,
151 List<Pair<Integer, List<ContextMenuItem>>> itemGroups) {
152 View view = LayoutInflater.from(context).inflate(R.layout.tabular_contex t_menu, null);
153
154 List<Pair<String, ViewGroup>> viewGroups = new ArrayList<>();
155 int maxCount = 0;
156 for (int i = 0; i < itemGroups.size(); i++) {
157 Pair<Integer, List<ContextMenuItem>> itemGroup = itemGroups.get(i);
158 maxCount = Math.max(maxCount, itemGroup.second.size());
159 }
160 for (int i = 0; i < itemGroups.size(); i++) {
161 Pair<Integer, List<ContextMenuItem>> itemGroup = itemGroups.get(i);
162 viewGroups.add(new Pair<>(context.getString(itemGroup.first),
163 createContextMenuPageUi(context, params, itemGroup.second, m axCount)));
164 }
165 TabularContextMenuViewPager pager =
166 (TabularContextMenuViewPager) view.findViewById(R.id.custom_page r);
167 pager.setAdapter(new TabularContextMenuPagerAdapter(viewGroups));
168
169 TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
170 if (itemGroups.size() <= 1) {
171 tabLayout.setVisibility(View.GONE);
172 }
173 tabLayout.setupWithViewPager((ViewPager) view.findViewById(R.id.custom_p ager));
174
175 return view;
176 }
177
178 @Override
179 public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
180 mDialog.dismiss();
181 mCallback.onResult((int) id);
182 }
183 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698