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

Commit ffe4671

Browse files
committed
replaced ToolbarLayout menu with PopupMenu, PopupMenu improvements
1 parent fcb7c07 commit ffe4671

File tree

4 files changed

+51
-196
lines changed

4 files changed

+51
-196
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import android.view.View;
1515
import android.view.inputmethod.InputMethodManager;
1616
import android.widget.LinearLayout;
17-
import android.widget.Toast;
1817

1918
import androidx.appcompat.app.AppCompatActivity;
2019
import androidx.appcompat.util.SeslMisc;
@@ -345,7 +344,7 @@ private void popupView(View view) {
345344
if (bnvPopupMenu == null) {
346345
bnvPopupMenu = new PopupMenu(view);
347346
bnvPopupMenu.inflate(R.menu.bnv_menu);
348-
bnvPopupMenu.setOnMenuItemClickListener(item -> bnvPopupMenu.setMenuItemBadge(item, bnvPopupMenu.getOverflowMenuBadge(item) + 1));
347+
bnvPopupMenu.setOnMenuItemClickListener(item -> bnvPopupMenu.setMenuItemBadge(item, bnvPopupMenu.getMenuItemBadge(item) + 1));
349348
}
350349
bnvPopupMenu.show();
351350
}

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

Lines changed: 32 additions & 186 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package de.dlyt.yanndroid.oneui.layout;
22

33
import android.annotation.SuppressLint;
4-
import android.app.Activity;
54
import android.content.Context;
65
import android.content.ContextWrapper;
76
import android.content.res.Configuration;
@@ -11,22 +10,17 @@
1110
import android.util.AttributeSet;
1211
import android.util.Log;
1312
import android.util.TypedValue;
14-
import android.view.KeyEvent;
1513
import android.view.LayoutInflater;
1614
import android.view.Menu;
1715
import android.view.MenuInflater;
1816
import android.view.MenuItem;
19-
import android.view.MotionEvent;
2017
import android.view.View;
2118
import android.view.ViewGroup;
2219
import android.view.WindowManager;
23-
import android.widget.AdapterView;
24-
import android.widget.ArrayAdapter;
2520
import android.widget.CheckBox;
2621
import android.widget.CompoundButton;
2722
import android.widget.FrameLayout;
2823
import android.widget.LinearLayout;
29-
import android.widget.PopupWindow;
3024
import android.widget.RelativeLayout;
3125
import android.widget.TextView;
3226

@@ -45,17 +39,14 @@
4539
import java.lang.annotation.RetentionPolicy;
4640
import java.text.NumberFormat;
4741
import java.util.ArrayList;
48-
import java.util.HashMap;
4942
import java.util.Locale;
5043

5144
import de.dlyt.yanndroid.oneui.R;
5245
import de.dlyt.yanndroid.oneui.sesl.appbar.SamsungAppBarLayout;
5346
import de.dlyt.yanndroid.oneui.sesl.appbar.SamsungCollapsingToolbarLayout;
5447
import de.dlyt.yanndroid.oneui.sesl.support.ViewSupport;
5548
import de.dlyt.yanndroid.oneui.sesl.support.WindowManagerSupport;
56-
import de.dlyt.yanndroid.oneui.sesl.utils.ReflectUtils;
5749
import de.dlyt.yanndroid.oneui.sesl.widget.ActionModeBottomBarButton;
58-
import de.dlyt.yanndroid.oneui.sesl.widget.PopupListView;
5950
import de.dlyt.yanndroid.oneui.sesl.widget.ToolbarImageButton;
6051
import de.dlyt.yanndroid.oneui.view.PopupMenu;
6152

@@ -93,12 +84,9 @@ public class ToolbarLayout extends LinearLayout {
9384
private LinearLayout actionButtonContainer;
9485
private FrameLayout overflowButtonContainer;
9586
private ToolbarImageButton overflowButton;
96-
private PopupWindow overflowMenuPopupWindow = null;
97-
private OverflowMenuAdapter overflowMenuPopupAdapter;
9887
private View overflowMenuPopupAnchor = null;
99-
private int overflowMenuPopupOffX;
88+
private PopupMenu popupMenu;
10089
private Menu menu;
101-
private HashMap<MenuItem, Integer> overflowBadges = new HashMap<>();
10290
private OnMenuItemClickListener onMenuItemClickListener = item -> {
10391
};
10492

@@ -367,20 +355,25 @@ public void setActionModeBottomMenu(@MenuRes int menuRes, OnMenuItemClickListene
367355
}
368356

369357
if (!bottomItems.isEmpty()) {
370-
ActionModeBottomBarButton button = new ActionModeBottomBarButton(mContext);
371-
button.setText(getResources().getString(R.string.sesl_more_item_label));
372-
button.setIcon(getResources().getDrawable(R.drawable.ic_samsung_more, getContext().getTheme()));
373-
footer_action_mode.addView(button);
374-
375-
PopupMenu popupMenu = new PopupMenu(button);
376-
popupMenu.inflate(bottomItems);
377-
popupMenu.setOnMenuItemClickListener(item -> {
378-
popupMenu.dismiss();
358+
ActionModeBottomBarButton moreButton = new ActionModeBottomBarButton(mContext);
359+
moreButton.setText(getResources().getString(R.string.sesl_more_item_label));
360+
moreButton.setIcon(getResources().getDrawable(R.drawable.ic_samsung_more, getContext().getTheme()));
361+
footer_action_mode.addView(moreButton);
362+
363+
PopupMenu actionPopupMenu = new PopupMenu(moreButton);
364+
actionPopupMenu.inflate(bottomItems);
365+
actionPopupMenu.setOnMenuItemClickListener(item -> {
366+
actionPopupMenu.dismiss();
379367
onActionModeItemClickListener.onMenuItemClick(item);
380368
});
381369

382-
button.setOnClickListener(v -> {
383-
popupMenu.show();
370+
moreButton.setOnClickListener(v -> {
371+
int xoff = actionPopupMenu.getPopupMenuWidth() - moreButton.getWidth() + 7;
372+
if (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
373+
actionPopupMenu.show(xoff, 0);
374+
} else {
375+
actionPopupMenu.show(-xoff, 0);
376+
}
384377
});
385378

386379
}
@@ -503,7 +496,6 @@ public void inflateMenu(@MenuRes int resId) {
503496
if (((MenuItemImpl) item).requiresActionButton()) {
504497
addActionButton(item);
505498
} else {
506-
overflowBadges.put(item, 0);
507499
overflowItems.add(item);
508500
}
509501
}
@@ -535,6 +527,13 @@ private void addActionButton(MenuItem item) {
535527
}
536528

537529
private void setOverflowMenu(ArrayList<MenuItem> overflowItems) {
530+
popupMenu = new PopupMenu(overflowMenuPopupAnchor);
531+
popupMenu.inflate(overflowItems);
532+
popupMenu.setOnMenuItemClickListener(item -> {
533+
popupMenu.dismiss();
534+
onMenuItemClickListener.onMenuItemClick(item);
535+
});
536+
538537
if (overflowButton == null) {
539538
if (actionButtonContainer.getChildCount() != 0) {
540539
for (int i = 0; i < actionButtonContainer.getChildCount(); i++) {
@@ -556,93 +555,29 @@ private void setOverflowMenu(ArrayList<MenuItem> overflowItems) {
556555
overflowButton.setBackgroundResource(R.drawable.sesl_action_bar_item_background);
557556
overflowButton.setImageResource(R.drawable.sesl_ic_menu_overflow);
558557
overflowButton.setPaddingRelative(getResources().getDimensionPixelSize(R.dimen.sesl_action_bar_overflow_padding_start), 0, getResources().getDimensionPixelSize(R.dimen.sesl_action_bar_overflow_padding_end), 0);
559-
overflowButton.setOnClickListener(new View.OnClickListener() {
560-
@Override
561-
public void onClick(View v) {
562-
showOverflowMenu();
558+
overflowButton.setOnClickListener(v -> {
559+
if (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
560+
popupMenu.show(popupMenu.getPopupMenuWidth(), 0);
561+
} else {
562+
popupMenu.show(-popupMenu.getPopupMenuWidth(), 0);
563563
}
564564
});
565565
overflowButton.setTooltipText(getResources().getString(R.string.sesl_more_options));
566566

567567
overflowButtonContainer.addView(overflowButton, lp2);
568568
}
569-
570-
if (overflowMenuPopupWindow != null) {
571-
if (overflowMenuPopupWindow.isShowing()) {
572-
overflowMenuPopupWindow.dismiss();
573-
}
574-
overflowMenuPopupWindow = null;
575-
}
576-
PopupListView listView = new PopupListView(mContext);
577-
overflowMenuPopupAdapter = new OverflowMenuAdapter(getActivity(), overflowItems);
578-
listView.setAdapter(overflowMenuPopupAdapter);
579-
listView.setMaxHeight(getResources().getDimensionPixelSize(R.dimen.sesl_menu_popup_max_height));
580-
listView.setDivider(null);
581-
listView.setSelector(getResources().getDrawable(R.drawable.sesl_list_selector, mContext.getTheme()));
582-
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
583-
@Override
584-
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
585-
onMenuItemClickListener.onMenuItemClick((MenuItem) overflowMenuPopupAdapter.getItem(position));
586-
}
587-
});
588-
589-
if (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
590-
overflowMenuPopupOffX = getOverflowMenuPopupWidth(overflowMenuPopupAdapter);
591-
} else {
592-
overflowMenuPopupOffX = -getOverflowMenuPopupWidth(overflowMenuPopupAdapter);
593-
}
594-
595-
overflowMenuPopupWindow = new PopupWindow(listView);
596-
overflowMenuPopupWindow.setWidth(getOverflowMenuPopupWidth(overflowMenuPopupAdapter));
597-
overflowMenuPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
598-
overflowMenuPopupWindow.setAnimationStyle(R.style.MenuPopupAnimStyle);
599-
overflowMenuPopupWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.sesl_menu_popup_background, mContext.getTheme()));
600-
overflowMenuPopupWindow.setOutsideTouchable(true);
601-
overflowMenuPopupWindow.setElevation(getDIPForPX(12));
602-
overflowMenuPopupWindow.setFocusable(true);
603-
if (overflowMenuPopupWindow.isClippingEnabled()) {
604-
overflowMenuPopupWindow.setClippingEnabled(false);
605-
}
606-
overflowMenuPopupWindow.getContentView().setOnKeyListener(new View.OnKeyListener() {
607-
@Override
608-
public boolean onKey(View view, int i, KeyEvent keyEvent) {
609-
if (keyEvent.getKeyCode() != KeyEvent.KEYCODE_MENU || keyEvent.getAction() != KeyEvent.ACTION_UP || !overflowMenuPopupWindow.isShowing()) {
610-
return false;
611-
}
612-
overflowMenuPopupWindow.dismiss();
613-
return true;
614-
}
615-
});
616-
overflowMenuPopupWindow.setTouchInterceptor(new View.OnTouchListener() {
617-
@Override
618-
public boolean onTouch(View view, MotionEvent motionEvent) {
619-
if (motionEvent.getAction() != MotionEvent.ACTION_OUTSIDE) {
620-
return false;
621-
}
622-
overflowMenuPopupWindow.dismiss();
623-
return true;
624-
}
625-
});
626569
}
627570

628571
@SuppressLint("RestrictedApi")
629572
public void setOverflowMenuBadge(MenuItem item, Integer badge) {
630573
if (!((MenuItemImpl) item).requiresActionButton()) {
631-
overflowBadges.put(item, badge);
632-
overflowMenuPopupAdapter.notifyDataSetChanged();
633-
634-
int count = 0;
635-
boolean n = false;
636-
for (Integer i : overflowBadges.values()) if (i > 0) count += i;
637-
showOverflowMenuButtonBadge(count == 0 ? (n ? N_BADGE : 0) : count);
638-
639-
overflowMenuPopupWindow.setWidth(getOverflowMenuPopupWidth(overflowMenuPopupAdapter));
640-
if (overflowMenuPopupWindow.isShowing()) overflowMenuPopupWindow.dismiss();
574+
popupMenu.setMenuItemBadge(item, badge);
575+
showOverflowMenuButtonBadge(popupMenu.getTotalBadgeCount());
641576
}
642577
}
643578

644579
public Integer getOverflowMenuBadge(MenuItem item) {
645-
return overflowBadges.get(item);
580+
return popupMenu.getMenuItemBadge(item);
646581
}
647582

648583
private void showOverflowMenuButtonBadge(int count) {
@@ -675,23 +610,6 @@ private void showOverflowMenuButtonBadge(int count) {
675610
}
676611
}
677612

678-
@SuppressLint("LongLogTag")
679-
public void showOverflowMenu() {
680-
if (overflowMenuPopupWindow != null && !overflowMenuPopupWindow.isShowing()) {
681-
overflowMenuPopupWindow.showAsDropDown(overflowMenuPopupAnchor, overflowMenuPopupOffX, 0);
682-
((View) ReflectUtils.genericGetField(overflowMenuPopupWindow, "mBackgroundView")).setClipToOutline(true);
683-
} else
684-
Log.w(TAG + ".showMoreMenuPopupWindow", "moreMenuPopupWindow is null or already shown.");
685-
}
686-
687-
@SuppressLint("LongLogTag")
688-
public void dismissOverflowMenu() {
689-
if (overflowMenuPopupWindow != null && overflowMenuPopupWindow.isShowing()) {
690-
overflowMenuPopupWindow.dismiss();
691-
} else
692-
Log.w(TAG + ".dismissMoreMenuPopupWindow", "moreMenuPopupWindow is null or already hidden.");
693-
}
694-
695613
private ToolbarImageButton getOverflowIcon(int index) {
696614
if (actionButtonContainer != null && actionButtonContainer.getChildCount() != 0) {
697615
return (ToolbarImageButton) actionButtonContainer.getChildAt(index);
@@ -701,78 +619,6 @@ private ToolbarImageButton getOverflowIcon(int index) {
701619
}
702620
}
703621

704-
private int getOverflowMenuPopupWidth(OverflowMenuAdapter adapter) {
705-
int makeMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
706-
int popupWidth = 0;
707-
708-
for (int i = 0; i < adapter.getCount(); i++) {
709-
View view = adapter.getView(i, null, new LinearLayout(mContext));
710-
view.measure(makeMeasureSpec, makeMeasureSpec);
711-
int measuredWidth = view.getMeasuredWidth();
712-
if (measuredWidth > popupWidth) {
713-
popupWidth = measuredWidth;
714-
}
715-
}
716-
return popupWidth;
717-
718-
}
719-
720-
private class OverflowMenuAdapter extends ArrayAdapter {
721-
Activity activity;
722-
ArrayList<MenuItem> overflowItems;
723-
724-
public OverflowMenuAdapter(Activity instance, ArrayList<MenuItem> overflowItems) {
725-
super(instance, 0);
726-
this.activity = instance;
727-
this.overflowItems = overflowItems;
728-
}
729-
730-
@Override
731-
public int getCount() {
732-
return overflowItems.size();
733-
}
734-
735-
@Override
736-
public Object getItem(int position) {
737-
return overflowItems.get(position);
738-
}
739-
740-
@Override
741-
public View getView(int index, View view, ViewGroup parent) {
742-
TextView titleText;
743-
TextView badgeIcon;
744-
745-
view = ((LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.menu_popup_item_layout, parent, false);
746-
titleText = view.findViewById(R.id.more_menu_popup_title_text);
747-
titleText.setText(overflowItems.get(index).getTitle());
748-
749-
badgeIcon = view.findViewById(R.id.more_menu_popup_badge);
750-
Integer badgeCount = overflowBadges.get(overflowItems.get(index));
751-
752-
if (badgeCount > 0) {
753-
int count = badgeCount;
754-
if (count > 99) {
755-
count = 99;
756-
}
757-
String countString = numberFormat.format((long) count);
758-
badgeIcon.setText(countString);
759-
int width = (int) (getResources().getDimension(R.dimen.sesl_badge_default_width) + (float) countString.length() * getResources().getDimension(R.dimen.sesl_badge_additional_width));
760-
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) badgeIcon.getLayoutParams();
761-
lp.width = width;
762-
badgeIcon.setLayoutParams(lp);
763-
badgeIcon.setVisibility(View.VISIBLE);
764-
} else if (badgeCount == N_BADGE) {
765-
badgeIcon.setText("N");
766-
badgeIcon.setVisibility(View.VISIBLE);
767-
} else {
768-
badgeIcon.setVisibility(View.GONE);
769-
}
770-
771-
return view;
772-
}
773-
}
774-
775-
776622
public View getView(@ToolbarLayoutView int view) {
777623
switch (view) {
778624
case APPBAR_LAYOUT:

yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/widget/ActionModeBottomBarButton.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public ActionModeBottomBarButton(Context context) {
3232
icon = new ImageView(getContext());
3333
int iconSize = (int) getResources().getDimension(R.dimen.bottom_bar_item_image_size);
3434
LinearLayout.LayoutParams iconParams = new LinearLayout.LayoutParams(iconSize, iconSize);
35-
containerParams.setMargins(0, 0, 0, 1);
35+
iconParams.setMargins(0, 0, 0, 1);
3636
icon.setLayoutParams(iconParams);
3737
icon.setColorFilter(ContextCompat.getColor(getContext(), R.color.bottom_bar_item_image_color), android.graphics.PorterDuff.Mode.SRC_IN);
3838
addView(icon);

0 commit comments

Comments
 (0)