0

I'm binding this library:

https://github.com/mancj/MaterialSearchBar

And generally, it works, however, I have an issue when I try to add the support of the RecyclerView, I added the following libraries:

And I got the following errors:

I tried to follow this advice of creating some partial classes:

xamarin.android binding thorw 'does not implement inherited abstract member 'RecyclerView.Adapter.OnCreateViewHolder(ViewGroup, int)'

But it didn't work and I started to get duplicates, personally, I believe the main issue is here:

Severity Code Description Project File Line Suppression State Error CS0115 'SuggestionsAdapter.OnBindViewHolder(Object, int)': no suitable method found to override Xamarin-MaterialSearchBar C:\Users\feder\source\repos\Xamarin-MaterialSearchBar\Xamarin-MaterialSearchBar\obj\Release\generated\src\Com.Mancj.Materialsearchbar.Adapter.SuggestionsAdapter.cs 666 Active

This is the configuration of my VS 2019:

img1

img1

The only dependencies in the Gradle of the project are the following ones:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    testImplementation 'junit:junit:4.12'
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.android.support:cardview-v7:28.0.0'
}

If you want the compiled aar file and the project to test it.

Which as you can see I have them all. Any idea, what am I missing? Thanks.

Federico Navarrete
  • 3,069
  • 5
  • 41
  • 76

2 Answers2

0

try this,

1.add below lines in your Xamarin-MaterialSearchBar - Transforms - Metadata.xml

<remove-node path="/api/package[@name='com.mancj.materialsearchbar.adapter']/class[@name='SuggestionsAdapter']/method[@name='onBindViewHolder']" />

2.in your Xamarin-MaterialSearchBar - Additions,create a partial class DefaultSuggestionsAdapter

namespace Com.Mancj.Materialsearchbar.Adapter
{
  partial class DefaultSuggestionsAdapter
   {
     public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
      {
        throw new NotImplementedException();
      }

     public override void OnBindSuggestionHolder(Object p0, Object p1, int p2)
      {
        throw new NotImplementedException();
      }
   }
}

You could also refer to : Java Binding Abstract class not being generated.

Leo Zhu
  • 15,726
  • 1
  • 7
  • 23
  • Hi, I noticed this idea it's complicated because the methods like OnBindSuggestionHolder, SingleViewHeight or OnBindViewHolder from the SuggestionsAdapter are gone in the generated code because in the crashing code they are there. Any idea why? I'd say it happens the same in the other case. – Federico Navarrete Jun 24 '19 at 19:01
  • I changed your extends from java.lang.Object to RecyclerView.Adapter and then I get the same error, my guess is that the binder is replacing the inheritance from the RecyclerView.Adapter to java.lang.Object – Federico Navarrete Jun 24 '19 at 19:12
  • could you share your project?That might help to find errors faster – Leo Zhu Jun 25 '19 at 03:25
  • Hi, the project is here: https://www.dropbox.com/home/MaterialSearchBar, but it's used, you have this code in Java: @Override public void onBindViewHolder(V holder, int position) { onBindSuggestionHolder(suggestions.get(position), holder, position); } However, oddly the binder cannot find it and this is a basic method from the Recycler https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter – Federico Navarrete Jun 25 '19 at 04:22
  • Thanks because it's odd I cannot understand why it's not capable of overriding the method that is a basic method of the RecyclerView.Adapter. – Federico Navarrete Jun 25 '19 at 06:45
  • It doesn't work, it tells me: Partial class with single part and then I got two errors: OnBindSuggestionHolder no suitable method to override and the next one: does not implement the inherited abstract class. I have also a doubt, we're removing the onBindViewHolder from the base class, but adding it to the inherited one. My confusion is that if you want to create a custom adapter, I guess we should use the base class, also, I think your assumption is correct RecyclerView.ViewHolder about this because VS creates something odd by default. – Federico Navarrete Jun 26 '19 at 06:01
  • I think I made it work, I got an idea from you, but what I did is to re-write the Java class into C#. Thanks! – Federico Navarrete Jun 26 '19 at 17:43
0

How to fix this issue? Technically, it's not so simple, the best solution and there are 6 steps to follow:

  1. Add the following NuGet Packages:

    These are the minimum requirements found in the build.gradle.

  2. Remove the class SuggestionsAdapter from the future library from your Metadata.xml with this piece of code (inspired by the Leo Zhu - MSFT' answer).

    <remove-node path="/api/package[@name='com.mancj.materialsearchbar.adapter']/class[@name='SuggestionsAdapter']" />

    Why? Because this section of the code is not properly ported to C# by the binder; perhaps, the reason is that the V represents the RecyclerView.ViewHolder and it's too generic for the binder. You can see the original code here: SuggestionsAdapter.java

    Also, you might ask why I chose to migrate the SuggestionsAdapter over the DefaultSuggestionsAdapter. There are 2 reasons:

    • SuggestionsAdapter is the base class.
    • DefaultSuggestionsAdapter calls XML codes that you cannot access from C#, you can see them in the lines 34, 55 and 56.
  3. Build your library.

  4. Create a new folder in your Additions called Adapter where you need to create a class called SuggestionsAdapter.

  5. Migrate the code from Java to C#.

    namespace Com.Mancj.Materialsearchbar.Adapter
    {
        public abstract class SuggestionsAdapter<S, V> : RecyclerView.Adapter, IFilterable
        {
            private readonly LayoutInflater Inflater;
            protected List<S> Suggestions = new List<S>();
            protected List<S> Suggestions_clone = new List<S>();
            protected int MaxSuggestionsCount = 5;
    
            public void AddSuggestion(S r)
            {
                if (MaxSuggestionsCount <= 0)
                {
                    return;
                }
    
                if (r == null)
                {
                    return;
                }
                if (!Suggestions.Contains(r))
                {
                    if (Suggestions.Count >= MaxSuggestionsCount)
                    {
                        Suggestions.RemoveAt(MaxSuggestionsCount - 1);
                    }
                    Suggestions.Insert(0, r);
                }
                else
                {
                    Suggestions.Remove(r);
                    Suggestions.Insert(0, r);
                }
                Suggestions_clone = Suggestions;
                NotifyDataSetChanged();
            }
    
            public void SetSuggestions(List<S> suggestions)
            {
                Suggestions = suggestions;
                Suggestions_clone = suggestions;
                NotifyDataSetChanged();
            }
    
            public void ClearSuggestions()
            {
                Suggestions.Clear();
                Suggestions_clone = Suggestions;
                NotifyDataSetChanged();
            }
    
            public void DeleteSuggestion(int position, S r)
            {
                if (r == null)
                {
                    return;
                }
                //delete item with animation
                if (Suggestions.Contains(r))
                {
                    NotifyItemRemoved(position);
                    Suggestions.Remove(r);
                    Suggestions_clone = Suggestions;
                }
            }
    
            public List<S> GetSuggestions()
            {
                return Suggestions;
            }
    
            public int GetMaxSuggestionsCount()
            {
                return MaxSuggestionsCount;
            }
    
            public void SetMaxSuggestionsCount(int maxSuggestionsCount)
            {
                MaxSuggestionsCount = maxSuggestionsCount;
            }
    
            protected LayoutInflater GetLayoutInflater()
            {
                return Inflater;
            }
    
            public SuggestionsAdapter(LayoutInflater inflater)
            {
                Inflater = inflater;
            }
    
            public abstract int GetSingleViewHeight();
    
            public int GetListHeight()
            {
                return ItemCount * GetSingleViewHeight();
            }
    
            public abstract void OnBindSuggestionHolder(S suggestion, RecyclerView.ViewHolder holder, int position);
    
            public override int ItemCount => Suggestions.Count;
    
            public Filter Filter => null;
    
            public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
            {
                OnBindSuggestionHolder(Suggestions[position], holder, position);
            }
    
            public interface IOnItemViewClickListener
            {
                void OnItemClickListener(int position, View v);
                void OnItemDeleteListener(int position, View v);
            }
        }
    }
    
  6. Build your project again and that's all! Your library is fully working.

If you want to check the result.

Federico Navarrete
  • 3,069
  • 5
  • 41
  • 76