Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MultiAutoCompleteTextView with Custom Adapter displays garbled string

This is a follow up to my question earlier here: Android: Autocomplete TextView Similar To The Facebook App.

The Background:

My requirement in the question (link posted above) was to have an AutoCompleteTextView similar to the one used in the Facebook app and several others too. The solution was to use a multi-line MultiAutoCompleteTextView The idea was to enable users to type their Friends names directly while creating a Status Update. The solution in the answer works fine from a standalone point of view. However, when I stared integrating the solution in my existing code, it still works with the correct drop-down et all. I see the filtered list of my friends thanks to a solution from here: https://stackoverflow.com/a/12363961/1350013. I use a custom ListView with a BaseAdapter instead of the GridView from the solution.

The Problem:

My code makes use of a BaseAdapter which implements Filterable. As mentioned above, works fine.

When I select a Friend from the filtered list, is where the problem is. The MultiAutoCompleteTextView, after selection, displays this: @MY_PACKAGE_NAME.Friends.getFriends@406c1058 instead of the Friend's name. What would I have to change to show the Name instead of the garbled text? If it helps, the Class I run this in extends a SherlockActivity and not a SherlockListActivity.

Now I am not sure what the relevant code would be to find out where the problem might lie, so I will post as much relevant code as possible. I am a noob, so please be easy and ask for any additional code. I will promptly comply. Likewise, if something here is not needed is cluttering the post, I will remove that.

CODE BLOCKS

The Tokenizer from the solution from my earlier question. Linked at the top (In the onCreate() method)

editStatusUpdate = (MultiAutoCompleteTextView) findViewById(R.id.editStatusUpdate);
editStatusUpdate.addTextChangedListener(filterTextWatcher);

editStatusUpdate.setTokenizer(new Tokenizer() {

    @Override
    public CharSequence terminateToken(CharSequence text) {

        int i = text.length();

        while (i > 0 && text.charAt(i - 1) == ' ') {
            i--;
        }

        if (i > 0 && text.charAt(i - 1) == ' ') {
            return text;
        } else {
            if (text instanceof Spanned) {
                SpannableString sp = new SpannableString(text + " ");
                TextUtils.copySpansFrom((Spanned) text, 0, text.length(), Object.class, sp, 0);
                return sp;
            } else {
                return text.toString() + " ";
            }
        }
    }

    @Override
    public int findTokenStart(CharSequence text, int cursor) {

        int i = cursor;

        while (i > 0 && text.charAt(i - 1) != '@') {
            i--;
        }

        if (i < 1 || text.charAt(i - 1) != '@') {
            return cursor;
        }

        return i;
    }

    @Override
    public int findTokenEnd(CharSequence text, int cursor) {

        int i = cursor;
        int len = text.length();

        while (i < len) {
            if (text.charAt(i) == ' ') {
                return i;
            } else {
                i++;
            }
        }

        return len;

    }
});

The TextWatcher, also from the solution to the earlier question:

private TextWatcher filterTextWatcher = new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

        Layout layout = editStatusUpdate.getLayout();
        int pos = editStatusUpdate.getSelectionStart();
        int line = layout.getLineForOffset(pos);
        int baseline = layout.getLineBaseline(line);

        int bottom = editStatusUpdate.getHeight();

        editStatusUpdate.setDropDownVerticalOffset(baseline - bottom);

    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {

    }

    @Override
    public void afterTextChanged(Editable s) {

    }
};

For my ArrayList:

public class getFriends {

    String friendID;
    String friendName;
    String friendProfile;

    boolean selected;

    // SET FRIENDS ID
    public void setFriendID(String friendID) {
        this.friendID = friendID;
    }

    // GET FRIENDS ID
    public String getFriendID() {
        return friendID;
    }

    // SET FRIENDS NAME
    public void setFriendName(String friendName) {
        this.friendName = friendName;
    }

    // GET FRIENDS NAME
    public String getFriendName() {
        return friendName;
    }

    // SET FRIENDS PROFILE
    public void setFriendProfile(String friendProfile) {
        this.friendProfile = friendProfile;
    }

    // GET FRIENDS PROFILE
    public String getFriendProfile() {
        return friendProfile;
    }
}
like image 396
Siddharth Lele Avatar asked Oct 10 '12 06:10

Siddharth Lele


2 Answers

You should override convertResultToString(Object resultValue) in your filter, where Object is your class. This makes it possible to create a custom string for you class without relying on overriding the to String method.

like image 69
Heinrisch Avatar answered Nov 14 '22 21:11

Heinrisch


Judging by the output you get it appears that your code calls the toString method on your getClass objects to retrieve the data it needs. As you want the friend's name you should implement your own toString method(by overriding it) like this:

@Override
public String toString() {
    return friendName; 
}
like image 40
user Avatar answered Nov 14 '22 22:11

user