【问题标题】:MultiAutoCompleteTextView with Custom Adapter displays garbled string带有自定义适配器的 MultiAutoCompleteTextView 显示乱码字符串
【发布时间】:2012-10-10 06:49:49
【问题描述】:

这是对我之前的问题的跟进:Android: Autocomplete TextView Similar To The Facebook App

背景:

我在问题中的要求(上面发布的链接)是有一个类似于 Facebook 应用程序和其他几个应用程序中使用的AutoCompleteTextView。解决方案是使用多行MultiAutoCompleteTextView 这个想法是让用户能够在创建状态更新时直接输入他们的朋友姓名。从独立的角度来看,答案中的解决方案可以正常工作。但是,当我开始将解决方案集成到现有代码中时,它仍然适用于正确的下拉菜单等。多亏了这里的解决方案,我看到了我朋友的过滤列表:https://stackoverflow.com/a/12363961/1350013。我使用自定义ListViewBaseAdapter,而不是解决方案中的GridView

问题:

我的代码使用了实现FilterableBaseAdapter。如上所述,工作正常。

当我从过滤列表中选择一个朋友时,问题就出在哪里。 MultiAutoCompleteTextView 选择后显示:@MY_PACKAGE_NAME.Friends.getFriends@406c1058,而不是朋友的名字。我必须更改什么才能显示名称而不是乱码?如果有帮助,我在其中运行的类扩展了 SherlockActivity 而不是 SherlockListActivity

现在我不确定要找出问题所在的相关代码是什么,所以我会发布尽可能多的相关代码。我是菜鸟,所以请放轻松并要求提供任何其他代码。我会及时遵守。同样,如果这里不需要的东西弄乱了帖子,我会删除它。

代码块

Tokenizer 来自我之前问题的解决方案。在顶部链接(在onCreate() 方法中)

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;

    }
});

TextWatcher,同样来自前面问题的解决方案:

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) {

    }
};

对于我的 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;
    }
}

【问题讨论】:

  • 我还没有查看其他问题的代码,但似乎 toString 方法正在为您的 getFriends 类调用(顺便说一下可怕的命名)。尝试将覆盖的 toString 方法添加到 getFriends 类,如下所示:@Override public String toString() {return friendName;} 看看会发生什么。
  • 第一。评论中的解决方案立即奏效。因此,请将此添加为答案,我会接受它(带有设定的赏金):-)。第二。给班级命名的更好方法是什么?当您说可怕时,是否会引起对应用程序故障的任何担忧?还是只是不好的命名习惯?
  • 我用“可怕”夸大了,应用程序正常运行没有问题,只是你应该使用java约定(类名的大写字母)。此外,getFriends 可能不是一个好的选择,例如,当我第一次阅读您的问题时,getFriends 似乎更像是一个方法名称而不是一个类。作为你的班级,它是一个数据持有者,像FriendDataFriendInformation 这样的名字对于阅读你的代码的人来说可能是一个更具表现力的名字。这不是什么重要的事情,但如果你有其他人阅读它,你会帮助他们理解代码。
  • @Luksprog:感谢您的提示。我的应用程序中几乎所有类似的类都有这些名称,我会立即更改它们。再次感谢您的解决方案和提示。 :-)

标签: android baseadapter


【解决方案1】:

您应该在过滤器中覆盖 convertResultToString(Object resultValue),其中 Object 是您的类。这使得为​​您的类创建自定义字符串而不依赖于覆盖 to String 方法成为可能。

【讨论】:

  • 这应该是公认的答案。它更适合国际化,因为您不需要在模型对象中获取应用程序上下文。
【解决方案2】:

从您得到的输出来看,您的代码似乎在您的getClass 对象上调用了toString 方法来检索它需要的数据。当你想要朋友的名字时,你应该像这样实现自己的 toString 方法(通过覆盖它):

@Override
public String toString() {
    return friendName; 
}

【讨论】:

  • 这不是应该的做法(我什至会说这是错误的),有指定的方法进行这种转换。你不应该依赖函数 toString 方法。
猜你喜欢
  • 2016-07-16
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
  • 2013-05-21
  • 1970-01-01
  • 2023-03-17
  • 2013-10-07
  • 1970-01-01
相关资源
最近更新 更多