Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filterable RealmBaseAdapter and AutocompleteTextView #1726

Closed
gpulido opened this issue Nov 4, 2015 · 13 comments
Closed

Filterable RealmBaseAdapter and AutocompleteTextView #1726

gpulido opened this issue Nov 4, 2015 · 13 comments

Comments

@gpulido
Copy link

gpulido commented Nov 4, 2015

Hello,
I'm trying to populate an AutocompleteTextView with a list of "RealmResults" and filter the list while the user enter some keys.
I'm extending the RealmBaseAdapter as follows:

public abstract class FilterableRealmBaseAdapter<T extends RealmObject> extends RealmBaseAdapter<T>  implements Filterable{

    RealmResults<T> mRealmObjectList;
    public FilterableRealmBaseAdapter(Context context, RealmResults<T> realmObjectList, AppCompatAutoCompleteTextView refAutocomplete)
    {
        super(context, realmObjectList, true);
        mRealmObjectList  = realmObjectList;
        refAutocomplete.setAdapter(this);

    }

    @Override
    public int getCount() {
        return mRealmObjectList.size();
    }

    @Override
    public T getItem(int position) {
        return mRealmObjectList.get(position);
    }

    @Override
    public Filter getFilter() {
        return new Filter(){

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults result = new FilterResults();
                return result;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                RealmResults<T> realmResults = mRealmObjectList.where().contains("name", constraint.toString()).findAll();
                updateRealmResults(realmResults);
            }
        };
    }

AS the Filter class uses the perform filtering on a working thread different that the one is used to create the RealmResults, I just not use that and do the actual filtering process on the publishResults.
The problem is that the list is not being filtered. I have checked the realmResults after the "filter" phase on the publishResults method and it is filtered, but the list on the UI still contains all the items of the original realmResults.

What I am missing here?

Thank you
Gabriel

@zaki50 zaki50 changed the title Filerable RealmBaseAdapter and AutocompleteTextView Filterable RealmBaseAdapter and AutocompleteTextView Nov 5, 2015
@zaki50
Copy link
Contributor

zaki50 commented Nov 5, 2015

@gpulido Thank you for your report.

Filterable support is tracked in #646
I will merge this issue into #646 and will close this.

@zaki50 zaki50 closed this as completed Nov 5, 2015
@saket
Copy link

saket commented Nov 5, 2015

Realm searches are so fast, why do you even need to perform them in a background thread? :)

@gpulido
Copy link
Author

gpulido commented Nov 5, 2015

@Saketme I'm not, as you can see on the example code, I ignore the performfiltering method (is the one made in background) and do the actual filtering on the publish filter method. The problem is that the list is not being filtered on the UI.

@saket
Copy link

saket commented Nov 5, 2015

Ah. So in the meanwhile, you should try doing it without a Filter class then.

@gpulido
Copy link
Author

gpulido commented Nov 5, 2015

At this moment I'm just using a ArrayAdapter and handling manually the validation and texteditchanged but it is very patchy.

@freezy
Copy link

freezy commented Dec 1, 2015

@gpulido, do you have a snippet of your workaround to share?

@gpulido
Copy link
Author

gpulido commented Dec 1, 2015

@freezy I had to create a "mini POCO class" with just the basic info I need ffrom the original RealmObject, and transforming the RealmResults list to a list of this POCO class before creating a basic arrayAdapter. So at the end I'm holding a "non realm supported" list. As I'm using this just for a spinner that is being populated almost every time, it is not a problem. It is not the best or prettier solution but it works for me until Realm comes with a cleaner solution.
If you need the code for the filterable array adapter I could write it here, but once you are not using a RealmResult but a transformation of it (using Streams it is very straightforward and clean) it is not a "Realm based" solution anymore.

@freezy
Copy link

freezy commented Dec 1, 2015

I've tried something like this and filtering seems to work so far:

public class FilterableRealmAdapter<T extends RealmObject> extends ArrayAdapter<T> implements Filterable {

    final RealmResults<T> mRealmObjectList;
    List<T> mResults;

    public FilterableRealmBaseAdapter(Context context, RealmResults<T> realmObjectList, MaterialAutoCompleteTextView refAutocomplete) {
        super(context, android.R.layout.simple_list_item_1);
        mRealmObjectList = realmObjectList;
        refAutocomplete.setAdapter(this);
    }

    @Override
    public int getCount() {
        return mResults == null ? 0 : mResults.size();
    }

    @Override
    public T getItem(int position) {
        return mResults == null ? null : mResults.get(position);
    }

    @Override
    public Filter getFilter() {
        return new Filter() {

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                return new FilterResults();
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                if (constraint != null) {
                    mResults = mRealmObjectList.where().contains("name", String.valueOf(constraint)).findAll();
                    notifyDataSetChanged();
                }
            }
        };
    }
}

However, still need to figure out how to nicely populate the view, but this isn't Realm related.

It would be interesting to see your solution as well.

@saket
Copy link

saket commented Dec 1, 2015

There's one gotcha here if you're using an adapter based EditText (AutocompleteTextView, etc.). In the FilterResults object you're returning from performFiltering, make sure you set its count value > 0 or else the auto-complete dropdown will flicker every time the data-set is updated.

(To be more precise, AutocompleteTextView uses the count value to decide whether or not to show the dropdown. Returning 0 will cause it to hide and re-appear again when notifyDataSetChanged is called)

@gpulido
Copy link
Author

gpulido commented Dec 1, 2015

@freezy Your solution is very similar to my first approach (at the top of this issue), but you manage to solve the substitution of the filtered list (I don't know why I didn't figure out that way).
I'm going to change my code to use your approach and get ride of the streams and "POCO" class.
What is the problem you are having with the view? You already have solved the hard part.

@freezy
Copy link

freezy commented Dec 1, 2015

Alright, thanks for commenting. No particular problem with the view, I just hadn't done it at the time I posted the comment.

I'll paste the refactored class with @Saketme's input in #646.

@rahulbharsadiya
Copy link

rahulbharsadiya commented Dec 7, 2018

Realm searches are so fast, why do you even need to perform them in a background thread? :)

Hey,can you provide an example code on autocomplete textview ,where we put the filter data from realm objects,am a newbee,please do help

@Zhuinden
Copy link
Contributor

Zhuinden commented Dec 7, 2018

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants