0

I set up the following array adapter:

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_dropdown_item_1line, USERS);
    AutoCompleteTextView textView = (AutoCompleteTextView)
            findViewById(R.id.searchUserTextField);
    textView.setAdapter(adapter);

For the following String[] array:

private static final String[] USERS = new String[] {
        "user1", "user2", "user3", "user4", "user5"
};

The following is the XML for my searchUserTextField. Just a typical AutoCompleteTextView:

<AutoCompleteTextView
            android:layout_width="match_parent"
            android:layout_height="65dp"
            android:background="@drawable/edittext_border"
            android:layout_gravity="top"
            android:textColor="#000000"
            android:hint="@string/search_user"
            android:id="@+id/searchUserTextField"
            android:ems="150"
            android:paddingLeft="25dp"
            android:paddingTop="10dp"
            android:paddingRight="10dp"
            android:paddingBottom="10dp"
            android:maxLines ="4"
            android:maxLength ="150"
            android:scrollHorizontally="false"
            android:typeface="sans"
            android:textSize="14sp"
            android:fontFamily="sans-serif-light"
            android:capitalize="none"
            android:inputType="textEmailAddress"
            android:gravity="center_vertical"
            android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_toLeftOf="@+id/submitSearch"
            android:layout_toStartOf="@+id/submitSearch" />

So far, a very simple implementation.

I was wondering, how can I populate my USERS array with data retrieved from my User class in Parse? Basically, the use case is as follows:

1) User beings typing in AutoCompleteTextView,

2) suggestions pop up as a function of the available usernames in my Parse.com User class,

3) user selects the name and searches for the user.

I realize this probably isn't the correct or advanced implementation for what I'm trying to accomplish, but I just want to work on this in baby steps as I'm new to Android.

My question basically boils down to, how can I dynamically populate the USERS array with a list of Users from Parse based on input to the AutoCompleteTextView?


Update for Answer: I used the following in my application. I had to set this to getApplicationContext() in order for the ArrayAdapter to properly construct my custom strings array. Credit for answer goes to user hack_on below, but I had to change the context of my ArrayAdapter to get it working for my purposes.

    ParseQuery<ParseUser> userQuery = ParseUser.getQuery();
    userQuery.findInBackground(new FindCallback<ParseUser>() {
        public void done(List<ParseUser> parseUsers, ParseException e) {
            if (e == null) {
                Log.d("users", "Retrieved " + parseUsers.size());
                ParseUser[] data = parseUsers.toArray(new ParseUser[parseUsers.size()]);
                String[] strings = new String[data.length];
                for (int i = 0; i < data.length; i++) {
                    strings[i] = data[i].getString(ParseConstants.KEY_USERNAME);
                }
                // Test to see if it was correctly printing out the array I wanted.
                // System.out.println(Arrays.toString(strings));
                ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_dropdown_item_1line, strings);
                AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.searchUserTextField);
                if(parseUsers.size() < 40) textView.setThreshold(1);
                else textView.setThreshold(2);
                textView.setAdapter(adapter);
            } else {
                Log.d("users", "Error: " + e.getMessage());
            }
        }
    });
Martin Erlic
  • 5,467
  • 22
  • 81
  • 153
  • Is the String[] COUNTRIES meant to be USERS? I think you pass the array to the adapter and then change it. – hack_on Dec 15 '15 at 05:39
  • Yes, sorry. It was meant to be USERS. What I'm trying to figure out is how to build the array from a ParseUser query, or if that's even the right way to go about it. – Martin Erlic Dec 15 '15 at 09:41

2 Answers2

1

One of the (not accepted) answers to this question: Dynamically updating an AutoCompleteTextView adapter shows how to use a filter in the adapter to update the suggestions dynamically. You would have to implement the "autocomplete()" method and in your case return results from Parse.

EDIT: By dynamically populate, Op was asking to run a query before display of the list, not in response to user typing in the list.

ParseQuery<ParseUser> userQuery = ParseUser.getQuery();
    userQuery.findInBackground(new FindCallback<ParseUser>() {
        public void done(List<ParseUser> parseUsers, ParseException e) {
            if (e == null) {
                Log.d("score", "Retrieved " + parseUsers.size());
                ParseUser[] data = parseUsers.toArray(new ParseUser[parseUsers.size()]);
                String[] strings = new String[data.length];
                for (int i=0; i<data.length; i++) {
                    strings[i] = data[i].getString(ParseConstants.KEY_USER_REAL_NAME);
                }
                ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, strings);
                AutoCompleteTextView textView = (AutoCompleteTextView)
                        findViewById(R.id.searchUserTextField);
                if(parseUsers.size() < 40) textView.setThreshold(1);
                else textView.setThreshold(2);
                textView.setAdapter(adapter);
            } else {
                Log.d("score", "Error: " + e.getMessage());
            }
        }
    });
Community
  • 1
  • 1
hack_on
  • 2,532
  • 4
  • 26
  • 30
  • Interesting. I didn't realize you had to make a new string array to put into the array adapter. Looks like it should work but the array adapter doesn't seem to want to accept the new strings array. – Martin Erlic Dec 15 '15 at 22:47
  • The FindCallback isn't constructed in the ArrayAdapter. I had to change ``this`` to ``getApplicationContext()``, but then I get no response from the AutoCompleteTextView. Maybe I need a different type of array adapter? – Martin Erlic Dec 15 '15 at 23:00
  • Nevermind! And sorry for all the comments. I was querying the wrong ParseConstant. It was returning the object Ids of the users versus the usernames. This actually worked really well. Thanks! – Martin Erlic Dec 15 '15 at 23:06
  • Also, just a note to anyone who uses this, it will only return the very first 100 users created, which is all I wanted to get out of this exercise as I'm learning in steps. You can always add other constraints, but the query will always be limited by the 100 users within them. You'll have to implement some kind of onTextChangedListener or something else to run a query based on user input, such as the first letter typed into the AutoCompleteTextView. – Martin Erlic Dec 15 '15 at 23:45
0

Can't I do something like this?

            ParseQuery<ParseUser> userQuery = ParseUser.getQuery();
    userQuery.findInBackground(new FindCallback<ParseUser>() {
        public void done(List<ParseUser> parseUsers, ParseException e) {
            if (e == null) {
                Log.d("score", "Retrieved " + parseUsers.size());
                ParseUser[] data = parseUsers.toArray(new ParseUser[parseUsers.size()]);
                ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, data);
                AutoCompleteTextView textView = (AutoCompleteTextView)
                        findViewById(R.id.searchUserTextField);
                if(parseUsers.size() < 40) textView.setThreshold(1);
                else textView.setThreshold(2);
                textView.setAdapter(adapter);
            } else {
                Log.d("score", "Error: " + e.getMessage());
            }
        }
    });

I'm just getting an error on the following line:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, data);

It says "Cannot resolve constructor 'ArrayAdapter(com.Parse.FindCallback, int, com.parse.ParseUser[])'

Martin Erlic
  • 5,467
  • 22
  • 81
  • 153
  • That's because `ArrayAdapter` doesn't have a constructor defined that takes the arguments `com.Parse.FindCallback, int, com.parse.ParseUser[]` – kstandell Dec 15 '15 at 10:30
  • Neither does ParseQueryAdapter. Does that mean I have to make my own custom adapter class? – Martin Erlic Dec 15 '15 at 10:31
  • A custom `ArrayAdapter` could be an option. Take a look at [this](http://stackoverflow.com/questions/2265661/how-to-use-arrayadaptermyclass) for some info on how you might implement it. – kstandell Dec 15 '15 at 10:45
  • 1
    I had understood that by dynamic you meant you would run a query in response to what the user is typing. If you just mean run a query before putting the list up, I believe you will just have to loop through all the ParseUser items in data and add them to an appropriate data structure eg: put each data[i].getString(ParseConstants.KEY_USER_REAL_NAME) into a String[] which is created with the right size. – hack_on Dec 15 '15 at 11:37
  • Yes that's what I meant. The query would just collect all the usernames and plug them into an array. The String[] array can't be arbitrary? I have to know how many usernames are going into it beforehand? – Martin Erlic Dec 15 '15 at 11:45
  • Ill edit my answer to reflect what you were really asking. – hack_on Dec 15 '15 at 12:01