zawadz88 / materialpopupmenu Goto Github PK
View Code? Open in Web Editor NEWShows Material popup menus grouped in sections & more
License: Apache License 2.0
Shows Material popup menus grouped in sections & more
License: Apache License 2.0
To support accessibility features, I want to implement a 'TalkBack' for my menus. In a native implementation, I can add the contentDescription
to the menu items. How can I do the same with this library?
Looks like you allows only static way to create views.
it isn't possible to create a .dismiss() callback on the popupMenu? It would be nice to dismiss it programmatically or when the execution reaches the end of the callback
Error
When trying to do automated UI tests with Robolectric I get this error:
java.lang.IllegalAccessError: tried to access class kotlin.jvm.internal.DefaultConstructorMarker from class androidx.appcompat.widget.MaterialRecyclerViewPopupWindow$Companion
This is caused by MaterialRecyclerViewPopupWindow
being in the androidx
namespace so Robolectric does its bytecode magic on it.
Fix:
Don't put MaterialRecyclerViewPopupWindow in the androidx namespace.
Workaround:
Use a custom RobolectricTestRunner
* https://github.com/robolectric/robolectric/issues/4340
*
* https://github.com/zawadz88/MaterialPopupMenu/blob/master/material-popup-menu/src/main/java/androidx/appcompat/widget/MaterialRecyclerViewPopupWindow.kt
* MaterialRecyclerViewPopupWindow uses the androidx namespace, so Robolectric tries to instrument it, which doesn't turn out well.
*/
class CustomRobolectricTestRunner(testClass: Class<*>?, injector: Injector) : RobolectricTestRunner(testClass) {
private var androidConfigurer: AndroidConfigurer = injector.getInstance(AndroidConfigurer::class.java)
@Suppress("unused")
constructor(testClass: Class<*>?): this(testClass, defaultInjector().build())
override fun createClassLoaderConfig(method: FrameworkMethod?): InstrumentationConfiguration {
val configuration: ConfigurationStrategy.Configuration = (method as RobolectricFrameworkMethod).configuration
val config: Config = configuration.get(Config::class.java)
val builder = Builder(super.createClassLoaderConfig(method))
builder.doNotInstrumentClass("androidx.appcompat.widget.MaterialRecyclerViewPopupWindow\$Companion")
androidConfigurer.configure(builder, interceptors)
androidConfigurer.withConfig(builder, config)
return builder.build()
}
}
Is it possible to have a dismiss listener we could set, similar to the PopupWindow.setOnDismissListener
method?
Hi @zawadz88,
This is with respect to react-native-popover-menu: ISSUE 10
We have encountered below strange issues when the popover has scroll bar:
I have tried the same in example by adding more items, please find below output:
Please let me know incase more information is required for the same.
Thanks
Pranav
On the native framework, if you drag-touch from the overflow menu, you can still select an item.
This means a single touch is needed to show the popup till you select an item from it.
Is it possible to do it here too?
I've tested the sample, and it seems it doesn't work this way.
Hi!
Do you think it would be possible to add support for specifying the text color of each item?
I can also give it a look if you point me into the right direction to develop this feature ๐
If you are in inmmersive mode without navigation and statusbar and show the Popupmenu the NavigationBar is display because the popup window gains foccus.
This can be prevented and the library can be used without exit the immersive mode at all... making MaterialRecyclerViewPopupWindow no focussable on the private method buildDropDown
I am not able to position the popup menu below the view anchor like in this picture:
I have tried to set dropdownGravity = Gravity.BOTTOM
without success. I have also tested with other Gravity constants (i.e END, START, TOP, etc.) but wasn't able to achieve the desired result.
How can I make the dialog behind the background? And can you tell me how to center the label?
I don't have ideas how to fix that currently but calculation of height for the popup appears to work incorrectly when items can have dynamic height.
This can be easily reproduced with item that has long text applied in the viewBoundCallback
block like I've done with below code:
diff --git a/sample/src/main/java/com/github/zawadz88/materialpopupmenu/sample/LightActivity.kt b/sample/src/main/java/com/github/zawadz88/materialpopupmenu/sample/LightActivity.kt
index c1823d606dbf7d2d1d2a4cbff025bce15ff756d2..e6e5652772bc62f1e91584cb7321141d0d0a86d6 100644
--- a/sample/src/main/java/com/github/zawadz88/materialpopupmenu/sample/LightActivity.kt
+++ b/sample/src/main/java/com/github/zawadz88/materialpopupmenu/sample/LightActivity.kt
@@ -321,6 +321,10 @@ class LightActivity : AppCompatActivity() {
}
customItem {
layoutResId = R.layout.view_custom_item_large
+ viewBoundCallback = { view ->
+ val textView: TextView = view.findViewById(R.id.customItemTextView)
+ textView.text = "Some long text that is applied later to see if height calculation indeed is incorrectly calculated due to this binding."
+ }
}
}
}
diff --git a/sample/src/main/res/layout/view_custom_item_large.xml b/sample/src/main/res/layout/view_custom_item_large.xml
index 7223c7b5b7d2087b3dc02972de35a5686403ce01..4486a545636d298fad9ecf39ce87f1ede481eb34 100644
--- a/sample/src/main/res/layout/view_custom_item_large.xml
+++ b/sample/src/main/res/layout/view_custom_item_large.xml
@@ -1,24 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
style="@style/Widget.MPM.Item"
android:layout_width="match_parent"
- android:layout_height="96dp"
+ android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:gravity="center"
- android:orientation="horizontal"
- android:paddingEnd="@dimen/mpm_popup_menu_item_padding_horizontal"
+ android:orientation="vertical"
+ android:paddingStart="@dimen/mpm_popup_menu_item_padding_horizontal"
android:paddingLeft="@dimen/mpm_popup_menu_item_padding_horizontal"
+ android:paddingEnd="@dimen/mpm_popup_menu_item_padding_horizontal"
android:paddingRight="@dimen/mpm_popup_menu_item_padding_horizontal"
- android:paddingStart="@dimen/mpm_popup_menu_item_padding_horizontal"
- tools:ignore="UseCompoundDrawables"
tools:theme="@style/Widget.MPM.Menu">
+ <TextView
+ android:id="@+id/customItemTextView"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ tools:text="Sample text" />
+
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- app:srcCompat="@mipmap/ic_launcher"/>
+ app:srcCompat="@mipmap/ic_launcher" />
</LinearLayout>
Hi there,
thank you for developing this library. However, I could not find a license file. Which license does this project use?
Thanks,
Yannik
I want to be able to modify the UI elements in the popup menu when the user clicks on them, however I can't do this right now because they private.
I think it would be better if they were public so that we could modify them or offer users a different way to modify them.
As Android Support libraries are being replaced by AndroidX (which is now stable), this library's dependencies should be updated as well.
https://developer.android.com/topic/libraries/support-library/androidx-overview
This will introduce breaking changes so a major version name update will be required.
Hi @zawadz88,
I am basically writing ReactNative native bridge of this library in order to using it with ReactNative projects.
I am stuck at place where from JS I am receiving icon information and using that I am able to create Drawable object, now the challenge is how to pass this drawable to item.setIcon
method.
Since this API only except drawable resource, I am not able to pass the created drawable. Is it possible to have one more method which accepts raw drawable, may be we can achieve this by method overloading.
Please find reference below to the ReactNative library which I am working on:
react-native-popover-menu
Bridging Class
In case if you are lined up with other assignments, can you please guide me on how to enable this API. I will try my level best in order to enable this functionality.
P.S: Please consider me as beginner with Kotlin
Thanks
Pranav
We need that some menu entries be visible, but be disabled because some users do not have sufficient permissions.
1. Use ViewBinding
I'd like to use ViewBinding
instead of View
in the viewBoundCallbacks
- I would integrate this. What do you think about that?
This would remove the need for putting findViewById(...)
calls into the callbacks.
As a side note, this callback could be used to easily replace all text/color adjustments but this would totally break backwards compatibility. But it would minimize the library functions...
2. Support more gravities
I'd like to add support for top/left/right/bottom and center here:
3. Height calculation optimisation
I think following can be optimised for large menus:
I think it would be save to stop iterating over the adapter items as soon as the total height has reached screen height, am I right?
Is there a way to set which item is selected/focused on menu opening?
for instance I have menu
----------
Option 1
Option 2 <- I want this item to be focused
Option 3
---------
Sometimes we would like to have our own very customized view to show in the popup.
Please offer what you have today, with the nice alignment , auto-positioning etc... - for a more generic popup.
popupMenu {
style = R.style.Widget_MPM_Menu_Custom
section { attachmentList?.forEach { item {
iconColor = Color.WHITE
labelColor = Color.WHITE
iconDrawable = it.icon
label = it.title
callback = { intent(it.url) }
} } }
R.style.Widget_MPM_Menu_Custom
is <style name="Widget.MPM.Menu.Custom"><item name="android:colorBackground">#ffaf00</item></style>
ย
val drawables = arrayListOf<Drawable>()
val popup = popupMenu {
style = R.style.Widget_MPM_Menu_Custom
dropDownVerticalOffset = toolBar.height
section { attachmentList?.forEach { item {
iconColor = white
labelColor = white
iconDrawable = it.icon
iconDrawable?.apply { drawables.add(this) }
label = it.title
callback = { intent(it.url) }
} } }
}
// Junky way to patch this bug.
popup.setOnDismissListener {
drawables.forEach { drawable ->
drawable.filter(white) } }
popup.show(context!!, it)
Hi @zawadz88
I am trying to using API's in Java, but I am getting error while adding item to section holder. Please find below snippet of the same:
ItemHolder item = new ItemHolder();
item.setLabel("Item 1");
SectionHolder section = new SectionHolder();
section.setTitle("Section");
section.item(item);
It is giving me below exception at last line:
Can you please guide me on how to add a item to section
Thanks
Pranav
Hi @zawadz88,
I am trying to set dark theme programatically using below API in Java:
MaterialPopupMenuBuilder popupMenuBuilder = new MaterialPopupMenuBuilder(); popupMenuBuilder.setStyle(R.style.Widget_MPM_Menu_Dark);
It is working as expected for text color but not for background color:
I am not sure if I am missing something, can you please guide on how to set the Dark theme programatically.
Thanks
Pranav
Hi @zawadz88
First of all I would like to appreciate for open sourcing such a nice library.
Do you any similar library for iOS platform as well?
Thanks
Pranav
When I try to run any of the tests via Android Studio I get an error similar to the one below. Is there anything I have to do/install before being able to run tests?
"com.github.zawadz88.materialpopupmenu.MaterialPopupMenuBuilderTest,Building a popup menu with an empty custom item in section should throw an exception"
java.lang.ExceptionInInitializerError
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker
at org.mockito.internal.configuration.plugins.PluginLoader$1.invoke(PluginLoader.java:66)
at com.sun.proxy.$Proxy7.isTypeMockable(Unknown Source)
at org.mockito.internal.util.MockUtil.typeMockabilityOf(MockUtil.java:29)
at org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:22)
at org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:186)
at org.mockito.internal.creation.MockSettingsImpl.confirm(MockSettingsImpl.java:180)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:62)
at org.mockito.Mockito.mock(Mockito.java:1729)
at com.github.zawadz88.materialpopupmenu.MaterialPopupMenuBuilderTest.<clinit>(MaterialPopupMenuBuilderTest.kt:317)
... 21 more
Caused by: java.lang.NoClassDefFoundError: net/bytebuddy/dynamic/loading/ClassLoadingStrategy
at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.<init>(SubclassByteBuddyMockMaker.java:33)
at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.<init>(ByteBuddyMockMaker.java:21)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:54)
at org.mockito.internal.configuration.plugins.PluginRegistry.<init>(PluginRegistry.java:18)
at org.mockito.internal.configuration.plugins.Plugins.<clinit>(Plugins.java:17)
at org.mockito.internal.util.MockUtil.<clinit>(MockUtil.java:24)
... 27 more
Caused by: java.lang.ClassNotFoundException: net.bytebuddy.dynamic.loading.ClassLoadingStrategy
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 38 more
Process finished with exit code -1
Could not determine the dependencies of task ':react-native-popover-menu:compileDebugAidl'.
> Could not resolve all task dependencies for configuration ':react-native-popover-menu:debugCompileClasspath'.
> Could not resolve com.github.zawadz88.materialpopupmenu:material-popup-menu:4.1.0.
Required by:
project :react-native-popover-menu
> Skipped due to earlier error
I need to open the menu centered horizontally. I can't find a way.
Currently, the only documentation available is in Github README. There's also Github Pages with Dokka documentation and a sample app with most APIs covered, but it feels to me that the documentation should be better.
There were many new features added recently (https://github.com/zawadz88/MaterialPopupMenu#supported-features) but the documentation in README does not cover it at the moment.
A better, more organized documentation might decrease the initial learning curve and make finding available APIs easier. It should probably be moved to Github pages - I don't feel like we should clutter README too much.
Ideally, I would like to have README similar to this https://github.com/aalmiray/kordamp-gradle-plugins and wiki page generated by Asciidoctor like here: https://aalmiray.github.io/kordamp-gradle-plugins/
Does the library supports multilevel menu ?
I would like to show a Popup Menu with the same width of anchor view. Is it possible to do so?
Hi, I'm a logo designer. I support open source projects with my logo designs. I would also like to make a contribution to the MaterialPopupMenu project. I have a great design idea. You want to see this?
Sometimes it may make sense to show menu entries with sub labels, can you add this as well?
E.g.:
[SECTION] "Change state"
[MENU 1] - "Mark completed"
[MENU 2] - "Mark completed"
[MENU 2 - SUB TEXT] "And add a comment"
Alternatively it would also work if we can provide a Spannable
as text, then we can do this with it's help as well. Of course, we would also need to disable the current single line only setting for each menu entry as well.
Gradle warning: kotlin-stdlib-jre7 is deprecated. Please use kotlin-stdlib-jdk7 instead
I checked the codes and could not find the code to add custom animations when the menu appears
The popup window is not dismissed when you tap outside. You can reproduce the problem using the sample provided.
minSdkVersion 21
targetSdkVersion 28
I have a java legacy project ans i want to try this libraire without using kotlin, my team have tout stay on java. How to ?
How can i use a menu resource file ?
i need change text size.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.