xamarin / AndroidX

AndroidX bindings for .NET for Android
MIT License
173 stars 42 forks source link

[Material] Slider.addOnChangeListener binding missing #230

Open tipa opened 3 years ago

tipa commented 3 years ago

Version Information

Describe your Issue:

Slider.IOnChangeListener is bound, but there is no way to add it to the Slider class, the addOnChangeListener method hasn't been bound

Steps to Reproduce (with link to sample solution if possible):

var slider = FindViewById<Google.Android.Material.Slider>(Resource.Id.my_slider);
slider.addOnChangeListener(listener); // compile error
slider.Change += Slider_Changed; // compile error
jpobst commented 3 years ago

Binding issue:

13>    BINDINGSGENERATOR : warning BG8800: Unknown parameter type L in method AddOnChangeListener in managed type Google.Android.Material.Slider.RangeSlider.
13>    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(61,5): message BG0000: warning BG8800: Unknown parameter type L in method AddOnChangeListener in managed type Google.Android.Material.Slider.RangeSlider.
13>    BINDINGSGENERATOR : warning BG8800: Unknown parameter type T in method AddOnSliderTouchListener in managed type Google.Android.Material.Slider.RangeSlider.
13>    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(61,5): message BG0000: warning BG8800: Unknown parameter type T in method AddOnSliderTouchListener in managed type Google.Android.Material.Slider.RangeSlider.
13>    BINDINGSGENERATOR : warning BG8800: Unknown parameter type L in method RemoveOnChangeListener in managed type Google.Android.Material.Slider.RangeSlider.
13>    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(61,5): message BG0000: warning BG8800: Unknown parameter type L in method RemoveOnChangeListener in managed type Google.Android.Material.Slider.RangeSlider.
13>    BINDINGSGENERATOR : warning BG8800: Unknown parameter type T in method RemoveOnSliderTouchListener in managed type Google.Android.Material.Slider.RangeSlider.
13>    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(61,5): message BG0000: warning BG8800: Unknown parameter type T in method RemoveOnSliderTouchListener in managed type Google.Android.Material.Slider.RangeSlider.
13>    BINDINGSGENERATOR : warning BG8800: Unknown parameter type L in method AddOnChangeListener in managed type Google.Android.Material.Slider.Slider.
13>    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(61,5): message BG0000: warning BG8800: Unknown parameter type L in method AddOnChangeListener in managed type Google.Android.Material.Slider.Slider.
13>    BINDINGSGENERATOR : warning BG8800: Unknown parameter type T in method AddOnSliderTouchListener in managed type Google.Android.Material.Slider.Slider.
13>    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(61,5): message BG0000: warning BG8800: Unknown parameter type T in method AddOnSliderTouchListener in managed type Google.Android.Material.Slider.Slider.
13>    BINDINGSGENERATOR : warning BG8800: Unknown parameter type L in method RemoveOnChangeListener in managed type Google.Android.Material.Slider.Slider.
13>    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(61,5): message BG0000: warning BG8800: Unknown parameter type L in method RemoveOnChangeListener in managed type Google.Android.Material.Slider.Slider.
13>    BINDINGSGENERATOR : warning BG8800: Unknown parameter type T in method RemoveOnSliderTouchListener in managed type Google.Android.Material.Slider.Slider.
13>    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Bindings.Core.targets(61,5): message BG0000: warning BG8800: Unknown parameter type T in method RemoveOnSliderTouchListener in managed type Google.Android.Material.Slider.Slider.
13>    BINDINGSGENERATOR : warning BG8700: Unknown return type P in method GetPrimaryAnimatorProvider in managed type Google.Android.Material.Transition.MaterialElevationScale.
ivmazurenko commented 3 years ago

Reproduced for RangeSlider too. Or maybe I should use other API ?

stalexig commented 3 years ago

Although have the same issue

ivmazurenko commented 3 years ago

Any updates?

tipa commented 3 years ago

workaround:

var method = Class.ForName("com.google.android.material.slider.BaseSlider").GetDeclaredMethods().FirstOrDefault(x => x.Name == "addOnChangeListener");
method?.Invoke(slider, this); // this is implementing IBaseOnChangeListener
moljac commented 3 years ago

Please try 1.3.0 and provide feedback here.

If it is not fixed automagically I will dive in next week

tipa commented 3 years ago

@moljac thanks for the new bindings - great stuff! 🥳 Unfortunately no magic fix for this issue :(

moljac commented 3 years ago

@tipa

Thanks.

OK. I will need to dig in. Hopefully soon

tipa commented 3 years ago

Friendly ping :) Would be great if this could be fixed so no workaround is necessary

tipa commented 2 years ago

Sadly, this issue is still present with 1.4.0

ibrahimmd90 commented 2 years ago

This is a workaround until they fix binding issue:

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState, Resource.Layout.my_activity);
    slider = FindViewById<Slider>(Resource.Id.slider);
    slider.Touch += Slider_Touch;
}

private void Slider_Touch(object sender, View.TouchEventArgs e)
{
    switch (e.Event.Action)
    {
        case MotionEventActions.Move:
        case MotionEventActions.Up:
            OnValueChange(slider, slider.Value, true);  //(Slider slider, float value, boolean fromUser)
            break;
    }
    e.Handled = false;
}

//This footprint matches native library callback
private void OnValueChange(Java.Lang.Object sender, float value, bool fromUser)
{
    //Do what you want to do as if you are listening to ValueChanged event (or at least very near to actual event)
}
xtuzy commented 2 years ago

1.4.0.5 still not work

jpobst commented 2 years ago

Moving my comment from #450 here:

Ugh, this one is a mess. According to the public documentation Slider is defined like this:

public class Slider extends View {
  public void addOnChangeListener (L listener) { ... }
}

One may be wondering what L is because it isn't specified anywhere. That's because decompiling the .jar shows that the public documentation is lying:

public class Slider extends BaseSlider<Slider, Slider.OnChangeListener, Slider.OnSliderTouchListener> 
{
 ...
}

abstract class BaseSlider<S extends BaseSlider<S, L, T>, L extends BaseOnChangeListener<S>, T extends BaseOnSliderTouchListener<S>> extends View 
{
  public void addOnChangeListener(@NonNull L listener) { ... }
}

That is, the public Slider class inherits from the private BaseSlider class, which isn't allowed in C#. Our tooling attempts to fix this and have Slider inherit from the public View instead, and copy all the methods that it can from the BaseSlider class directly into the Slider class.

However, due to the lack of generics support in our tooling, it is unable to copy the addOnChangeListener method which requires a generic parameter. Thus this method is dropped from the binding:

warning BG8800: Unknown parameter type 'L' for member 'Google.Android.Material.Slider.Slider.AddOnChangeListener (L)'.

I would suggest continuing to use the workaround listed above.

DavidMarquezF commented 1 year ago

Is there no progress with this. Right now it's not very convenient to use these controls

letscodewithkalyan commented 1 year ago

Still same with "1.8.0" version. Any progress ?

marcoburato-ecutek commented 1 year ago

I'm also affected by this.

I understand that updating the tooling to support this edge case would be hard, but is it not possible to add the required code manually in the bindings? I believe something like this is done, for instance, to add method overloads that accept .NET classes like System.Text.StringBuilder to improve interoperability between .NET and Java.

Zintom commented 9 months ago

Just me being nosy here, what's the tooling issue? Is it to do with all generic methods like this?

tipa commented 2 weeks ago
var method = Class.ForName("com.google.android.material.slider.BaseSlider").GetDeclaredMethods().FirstOrDefault(x => x.Name == "addOnChangeListener");
method?.Invoke(slider, this); // this is implementing IBaseOnChangeListener

With the latest Nuget packages, this warning now also shows the deprecation warning: While this type is 'public', Google considers it internal API and reserves the right to modify or delete it in the future. Use at your own risk

When trying to use the non-deprecated Slider.IOnChangeListener class (which inherits from IBaseOnChangeListener) it leads to other errors:

1>obj\Debug\net8.0-android\android\src\crc64cd18cf298694e84d\Dialog.java(4,8): javac.exe error JAVAC0000:  error: BaseOnChangeListener cannot be inherited with different arguments: <com.google.android.material.slider.Slider> and <>
1>obj\Debug\net8.0-android\android\src\crc64cd18cf298694e84d\Dialog.java(4,8): javac.exe error JAVAC0000: public class Dialog
1>obj\Debug\net8.0-android\android\src\crc64cd18cf298694e84d\Dialog.java(4,8): javac.exe error JAVAC0000:
1>obj\Debug\net8.0-android\android\src\crc64cd18cf298694e84d\Dialog.java(59,14): javac.exe error JAVAC0000:  error: name clash: class Dialog has two methods with the same erasure, yet neither overrides the other
1>obj\Debug\net8.0-android\android\src\crc64cd18cf298694e84d\Dialog.java(59,14): javac.exe error JAVAC0000:     public void onValueChange (com.google.android.material.slider.Slider p0, float p1, boolean p2)
1>obj\Debug\net8.0-android\android\src\crc64cd18cf298694e84d\Dialog.java(59,14): javac.exe error JAVAC0000:   first method:  onValueChange(Slider,float,boolean) in BaseOnChangeListener
1>obj\Debug\net8.0-android\android\src\crc64cd18cf298694e84d\Dialog.java(59,14): javac.exe error JAVAC0000:   second method: onValueChange(Object,float,boolean) in Dialog
1>obj\Debug\net8.0-android\android\src\crc64cd18cf298694e84d\Dialog.java(59,14): javac.exe error JAVAC0000:
1>obj\Debug\net8.0-android\android\src\crc64cd18cf298694e84d\Dialog.java(67,14): javac.exe error JAVAC0000:  error: name clash: onValueChange(Object,float,boolean) in Dialog and onValueChange(Slider,float,boolean) in BaseOnChangeListener have the same erasure, yet neither overrides the other
1>obj\Debug\net8.0-android\android\src\crc64cd18cf298694e84d\Dialog.java(67,14): javac.exe error JAVAC0000:     public void onValueChange (java.lang.Object p0, float p1, boolean p2)
1>obj\Debug\net8.0-android\android\src\crc64cd18cf298694e84d\Dialog.java(67,14): javac.exe error JAVAC0000:

It really would be appreciated if some working workaround could be provided by the bindings, without having to implement it by ourselves that causes build warnings