Skip to content
This repository was archived by the owner on Sep 3, 2024. It is now read-only.

Commit 0525d5e

Browse files
committed
PopupMenu rework, ThemeColor hsv fix
1 parent 84c2743 commit 0525d5e

File tree

5 files changed

+167
-77
lines changed

5 files changed

+167
-77
lines changed

app/src/main/java/de/dlyt/yanndroid/oneuiexample/MainActivity.java

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,14 @@
1414
import android.view.View;
1515
import android.view.inputmethod.InputMethodManager;
1616
import android.widget.LinearLayout;
17+
import android.widget.Toast;
1718

1819
import androidx.appcompat.app.AppCompatActivity;
1920
import androidx.appcompat.util.SeslMisc;
2021
import androidx.fragment.app.Fragment;
2122
import androidx.fragment.app.FragmentManager;
2223
import androidx.fragment.app.FragmentTransaction;
2324

24-
import java.util.ArrayList;
25-
import java.util.LinkedHashMap;
26-
2725
import de.dlyt.yanndroid.oneui.dialog.AlertDialog;
2826
import de.dlyt.yanndroid.oneui.dialog.ClassicColorPickerDialog;
2927
import de.dlyt.yanndroid.oneui.dialog.DetailedColorPickerDialog;
@@ -57,6 +55,7 @@ public class MainActivity extends AppCompatActivity {
5755
private DrawerLayout drawerLayout;
5856
private ToolbarLayout toolbarLayout;
5957
private BottomNavigationView bnvLayout;
58+
private PopupMenu bnvPopupMenu;
6059

6160
@Override
6261
protected void onCreate(Bundle savedInstanceState) {
@@ -343,22 +342,11 @@ public void onClick(View v) {
343342
}
344343

345344
private void popupView(View view) {
346-
PopupMenu popupMenu = new PopupMenu(view);
347-
ArrayList<String> list = new ArrayList<>();
348-
for (int i = 0; i < 4; i++) list.add("Menu Item " + i);
349-
popupMenu.inflate(list);
350-
popupMenu.setOnMenuItemClickListener((parent, view1, position, id) -> {
351-
popupMenu.dismiss();
352-
});
353-
popupMenu.show();
354-
}
355-
356-
357-
private LinkedHashMap<String, Integer> getMoreMenuButtonList() {
358-
LinkedHashMap linkedHashMap = new LinkedHashMap();
359-
linkedHashMap.put("Menu Item 1", 0);
360-
linkedHashMap.put("Menu Item 2", 87);
361-
linkedHashMap.put("Menu Item 3", ToolbarLayout.N_BADGE);
362-
return linkedHashMap;
345+
if (bnvPopupMenu == null) {
346+
bnvPopupMenu = new PopupMenu(view);
347+
bnvPopupMenu.inflate(R.menu.bnv_menu);
348+
bnvPopupMenu.setOnMenuItemClickListener(item -> bnvPopupMenu.setMenuItemBadge(item, bnvPopupMenu.getOverflowMenuBadge(item) + 1));
349+
}
350+
bnvPopupMenu.show();
363351
}
364352
}

app/src/main/res/menu/bnv_menu.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<menu xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<item android:title="Menu Item 1" />
5+
<item android:title="Menu Item 2" />
6+
<item android:title="Menu Item 3" />
7+
<item android:title="Menu Item 4" />
8+
<item android:title="Menu Item 5" />
9+
<item android:title="Menu Item 6" />
10+
11+
</menu>

yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/layout/ToolbarLayout.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -649,10 +649,6 @@ private class OverflowMenuAdapter extends ArrayAdapter {
649649
Activity activity;
650650
ArrayList<MenuItem> overflowItems;
651651

652-
public ArrayList<MenuItem> getOverflowItems() {
653-
return overflowItems;
654-
}
655-
656652
public OverflowMenuAdapter(Activity instance, ArrayList<MenuItem> overflowItems) {
657653
super(instance, 0);
658654
this.activity = instance;

yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/utils/ThemeColor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public static void setColor(AppCompatActivity activity, float red, float green,
105105

106106
public static void setColor(AppCompatActivity activity, float[] hsv) {
107107
int c = Color.HSVToColor(hsv);
108-
setColor(activity, Color.red(c) * 255, Color.green(c) * 255, Color.blue(c) * 255);
108+
setColor(activity, Color.red(c), Color.green(c), Color.blue(c));
109109
}
110110

111111
}

yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/view/PopupMenu.java

Lines changed: 147 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,33 @@
11
package de.dlyt.yanndroid.oneui.view;
22

3+
import android.annotation.SuppressLint;
4+
import android.app.Activity;
35
import android.content.Context;
6+
import android.content.ContextWrapper;
47
import android.util.TypedValue;
8+
import android.view.KeyEvent;
59
import android.view.LayoutInflater;
10+
import android.view.Menu;
11+
import android.view.MenuInflater;
12+
import android.view.MenuItem;
13+
import android.view.MotionEvent;
614
import android.view.View;
715
import android.view.ViewGroup;
816
import android.widget.AdapterView;
917
import android.widget.ArrayAdapter;
1018
import android.widget.LinearLayout;
11-
import android.widget.ListAdapter;
1219
import android.widget.PopupWindow;
1320
import android.widget.TextView;
1421

22+
import androidx.annotation.MenuRes;
23+
import androidx.appcompat.app.AppCompatActivity;
24+
import androidx.appcompat.view.SupportMenuInflater;
25+
import androidx.appcompat.view.menu.MenuBuilder;
26+
27+
import java.text.NumberFormat;
1528
import java.util.ArrayList;
29+
import java.util.HashMap;
30+
import java.util.Locale;
1631

1732
import de.dlyt.yanndroid.oneui.R;
1833
import de.dlyt.yanndroid.oneui.sesl.utils.ReflectUtils;
@@ -22,50 +37,102 @@ public class PopupMenu {
2237

2338
private Context context;
2439
private View anchor;
40+
private NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
41+
public static final int N_BADGE = -1;
42+
private OnMenuItemClickListener onMenuItemClickListener = item -> {
43+
};
2544

45+
private Menu menu;
2646
private PopupWindow popupWindow;
27-
private PopupListView listView;
2847
private PopupMenuAdapter popupMenuAdapter;
48+
private HashMap<MenuItem, Integer> overflowBadges = new HashMap<>();
2949

3050
public PopupMenu(View anchor) {
3151
this.context = anchor.getContext();
3252
this.anchor = anchor;
3353
}
3454

35-
public void inflate(ArrayList<String> menu) {
55+
public interface OnMenuItemClickListener {
56+
void onMenuItemClick(MenuItem item);
57+
}
58+
59+
public void setOnMenuItemClickListener(OnMenuItemClickListener listener) {
60+
onMenuItemClickListener = listener;
61+
}
62+
63+
public Menu getMenu() {
64+
return menu;
65+
}
66+
67+
@SuppressLint("RestrictedApi")
68+
public void inflate(@MenuRes int menuRes){
69+
menu = new MenuBuilder(context);
70+
MenuInflater menuInflater = new SupportMenuInflater(context);
71+
menuInflater.inflate(menuRes, menu);
72+
73+
ArrayList<MenuItem> menuItems = new ArrayList<>();
74+
75+
for (int i = 0; i < menu.size(); i++) {
76+
MenuItem item = menu.getItem(i);
77+
overflowBadges.put(item, 0);
78+
menuItems.add(item);
79+
}
80+
81+
if (menuItems.isEmpty()) return;
82+
3683
if (popupWindow != null) {
3784
if (popupWindow.isShowing()) {
3885
popupWindow.dismiss();
3986
}
4087
popupWindow = null;
4188
}
42-
43-
listView = new PopupListView(context);
44-
popupMenuAdapter = new PopupMenuAdapter(menu);
89+
PopupListView listView = new PopupListView(context);
90+
popupMenuAdapter = new PopupMenuAdapter(getActivity(), menuItems);
4591
listView.setAdapter(popupMenuAdapter);
4692
listView.setMaxHeight(context.getResources().getDimensionPixelSize(R.dimen.sesl_menu_popup_max_height));
4793
listView.setDivider(null);
48-
listView.setSelector(R.drawable.sesl_list_selector);
94+
listView.setSelector(context.getResources().getDrawable(R.drawable.sesl_list_selector, context.getTheme()));
95+
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
96+
@Override
97+
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
98+
onMenuItemClickListener.onMenuItemClick((MenuItem) popupMenuAdapter.getItem(position));
99+
}
100+
});
49101

50102
listView.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
51-
int height = listView.getMeasuredHeight() + context.getResources().getDimensionPixelSize(R.dimen.sesl_popup_menu_item_bottom_padding) -5;
103+
int height = listView.getMeasuredHeight() + context.getResources().getDimensionPixelSize(R.dimen.sesl_popup_menu_item_bottom_padding) - 5;
52104

53105
popupWindow = new PopupWindow(listView);
54106
popupWindow.setWidth(getPopupMenuWidth());
55107
popupWindow.setHeight(height);
56-
//popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
57108
popupWindow.setAnimationStyle(R.style.MenuPopupAnimStyle);
58-
popupWindow.setBackgroundDrawable(context.getDrawable(R.drawable.sesl_menu_popup_background));
109+
popupWindow.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.sesl_menu_popup_background, context.getTheme()));
59110
popupWindow.setOutsideTouchable(true);
60111
popupWindow.setElevation(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) 12, context.getResources().getDisplayMetrics()));
61112
popupWindow.setFocusable(true);
62113
if (popupWindow.isClippingEnabled()) {
63114
popupWindow.setClippingEnabled(false);
64115
}
65-
}
66-
67-
public void setOnMenuItemClickListener(AdapterView.OnItemClickListener listener) {
68-
listView.setOnItemClickListener(listener);
116+
popupWindow.getContentView().setOnKeyListener(new View.OnKeyListener() {
117+
@Override
118+
public boolean onKey(View view, int i, KeyEvent keyEvent) {
119+
if (keyEvent.getKeyCode() != KeyEvent.KEYCODE_MENU || keyEvent.getAction() != KeyEvent.ACTION_UP || !popupWindow.isShowing()) {
120+
return false;
121+
}
122+
popupWindow.dismiss();
123+
return true;
124+
}
125+
});
126+
popupWindow.setTouchInterceptor(new View.OnTouchListener() {
127+
@Override
128+
public boolean onTouch(View view, MotionEvent motionEvent) {
129+
if (motionEvent.getAction() != MotionEvent.ACTION_OUTSIDE) {
130+
return false;
131+
}
132+
popupWindow.dismiss();
133+
return true;
134+
}
135+
});
69136
}
70137

71138
public void show() {
@@ -81,71 +148,99 @@ public void dismiss() {
81148
popupWindow.dismiss();
82149
}
83150

84-
private int getPopupMenuWidth() {
85-
int makeMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
86-
View view = null;
87-
ViewGroup viewGroup = null;
88-
int measuredWidth = 0;
151+
public boolean isShowing(){
152+
return popupWindow.isShowing();
153+
}
89154

90-
int i = 0;
91-
int count = popupMenuAdapter.getCount();
92155

93-
while (i < count) {
94-
ViewGroup linearLayout;
95-
int itemViewType = popupMenuAdapter.getItemViewType(i);
156+
public void setMenuItemBadge(MenuItem item, Integer badge) {
157+
overflowBadges.put(item, badge);
158+
popupMenuAdapter.notifyDataSetChanged();
159+
popupWindow.setWidth(getPopupMenuWidth());
160+
if (popupWindow.isShowing()) popupWindow.dismiss();
161+
}
96162

97-
if (itemViewType != 0)
98-
view = null;
163+
public Integer getOverflowMenuBadge(MenuItem item) {
164+
return overflowBadges.get(item);
165+
}
99166

100-
if (viewGroup == null)
101-
linearLayout = new LinearLayout(context);
102-
else
103-
linearLayout = viewGroup;
167+
private int getPopupMenuWidth() {
168+
int makeMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
169+
int popupWidth = 0;
104170

105-
view = popupMenuAdapter.getView(i, view, linearLayout);
171+
for (int i = 0; i < popupMenuAdapter.getCount(); i++) {
172+
View view = popupMenuAdapter.getView(i, null, new LinearLayout(context));
106173
view.measure(makeMeasureSpec, makeMeasureSpec);
107-
measuredWidth = view.getMeasuredWidth();
108-
if (measuredWidth <= 0) {
109-
measuredWidth = 0;
174+
int measuredWidth = view.getMeasuredWidth();
175+
if (measuredWidth > popupWidth) {
176+
popupWidth = measuredWidth;
177+
}
178+
}
179+
return popupWidth;
180+
}
181+
182+
private AppCompatActivity getActivity() {
183+
while (context instanceof ContextWrapper) {
184+
if (context instanceof AppCompatActivity) {
185+
return (AppCompatActivity) context;
110186
}
111-
i++;
112-
viewGroup = linearLayout;
187+
context = ((ContextWrapper) context).getBaseContext();
113188
}
114-
return measuredWidth;
189+
return null;
115190
}
116191

192+
117193
private class PopupMenuAdapter extends ArrayAdapter {
118-
ArrayList<String> itemTitle;
194+
Activity activity;
195+
ArrayList<MenuItem> overflowItems;
119196

120-
public PopupMenuAdapter(ArrayList<String> itemTitle) {
121-
super(context, 0);
122-
this.itemTitle = itemTitle;
197+
public PopupMenuAdapter(Activity instance, ArrayList<MenuItem> overflowItems) {
198+
super(instance, 0);
199+
this.activity = instance;
200+
this.overflowItems = overflowItems;
123201
}
124202

125203
@Override
126204
public int getCount() {
127-
return itemTitle.size();
205+
return overflowItems.size();
128206
}
129207

130208
@Override
131209
public Object getItem(int position) {
132-
return itemTitle.get(position);
210+
return overflowItems.get(position);
133211
}
134212

135213
@Override
136214
public View getView(int index, View view, ViewGroup parent) {
137-
final TextView titleText;
138-
139-
if (view == null) {
140-
view = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.menu_popup_item_layout, parent, false);
141-
titleText = view.findViewById(R.id.more_menu_popup_title_text);
142-
view.setTag(titleText);
215+
TextView titleText;
216+
TextView badgeIcon;
217+
218+
view = ((LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.menu_popup_item_layout, parent, false);
219+
titleText = view.findViewById(R.id.more_menu_popup_title_text);
220+
titleText.setText(overflowItems.get(index).getTitle());
221+
222+
badgeIcon = view.findViewById(R.id.more_menu_popup_badge);
223+
Integer badgeCount = overflowBadges.get(overflowItems.get(index));
224+
225+
if (badgeCount > 0) {
226+
int count = badgeCount;
227+
if (count > 99) {
228+
count = 99;
229+
}
230+
String countString = numberFormat.format((long) count);
231+
badgeIcon.setText(countString);
232+
int width = (int) (context.getResources().getDimension(R.dimen.sesl_badge_default_width) + (float) countString.length() * context.getResources().getDimension(R.dimen.sesl_badge_additional_width));
233+
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) badgeIcon.getLayoutParams();
234+
lp.width = width;
235+
badgeIcon.setLayoutParams(lp);
236+
badgeIcon.setVisibility(View.VISIBLE);
237+
} else if (badgeCount == N_BADGE) {
238+
badgeIcon.setText("N");
239+
badgeIcon.setVisibility(View.VISIBLE);
143240
} else {
144-
titleText = (TextView) view.getTag();
241+
badgeIcon.setVisibility(View.GONE);
145242
}
146243

147-
titleText.setText(itemTitle.get(index));
148-
149244
return view;
150245
}
151246
}

0 commit comments

Comments
 (0)