【问题标题】:SectionIndexer shifted in mock contacts appSectionIndexer 在模拟联系人应用程序中移动
【发布时间】:2015-03-16 01:00:53
【问题描述】:

编辑:帖子底部的解决方案。

我正在为一个 Android 应用程序创建一个联系人屏幕,我希望能够在其中滚动浏览我的手机联系人。我可以导入手机联系人,使用自定义数组适配器来组织我的信息,并为列表视图启用快速滚动选项。此外,当我滚动时,我可以让当前部分的第一个字母出现在我的拇指旁边。 (即,如果我在名称以 A 开头的区域,它应该在我正在滚动的拇指旁边的气泡中显示“A”)。

我的问题是,它不是根据当前位置显示正确的字母,而是在我所在的位置显示 1 个字母。例如,我在联系人的 B 部分,它显示字母“A”。有什么想法我做错了吗?

这是我的适配器:

public class ContactAdapter extends ArrayAdapter<Contact> implements SectionIndexer {
    Context context;
    int layoutResourceId;
    ArrayList<Contact> contacts = null;

    private HashMap<String, Integer> alphaIndexer;
    private String[] sections;

    public ContactAdapter(Context context, int layoutResourceId, ArrayList<Contact> contacts) {
        super(context, layoutResourceId, contacts);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.contacts = contacts;

        Collections.sort(this.contacts);

        alphaIndexer = new HashMap<String, Integer>();
        for (int x = 0; x < this.contacts.size(); x++)
            alphaIndexer.put(this.contacts.get(x).getSection(), x);
        Set<String> sectionLetters = alphaIndexer.keySet();
        ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);
        Collections.sort(sectionList);
        sections = new String[sectionList.size()];
        sectionList.toArray(sections);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // Additional code here
    }

    static class ContactHolder {
        TextView txtName;
        CheckBox checked;
    }

    public int getPositionForSection(int section) {
        return alphaIndexer.get(sections[section]);
    }

    public int getSectionForPosition(int position) {
        return 0;
    }

    public Object[] getSections() {
        return sections;
    }
}

这是最终完成这项工作的代码:

public ContactAdapter(Context context, int layoutResourceId, ArrayList<Contact> contacts) {
    super(context, layoutResourceId, contacts);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.contacts = contacts;
    this.results = new ArrayList<Contact>();

    Collections.sort(this.contacts);

    // Keys are the different sections, values are the indexes at which those sections start
    alphaIndexer = new HashMap<String, Integer>();

    // Only set the value for each key (section) when we encounter a new section
    String prevSection = "";
    for (int x = 0; x < this.contacts.size(); x++) {
        String section = this.contacts.get(x).getSection();
        if (!prevSection.equals(section)) {
            alphaIndexer.put(section, x);
            prevSection = section;
        }
    }

    Set<String> sectionLetters = alphaIndexer.keySet();
    ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);
    Collections.sort(sectionList);
    sections = new String[sectionList.size()];
    sectionList.toArray(sections);
}

【问题讨论】:

    标签: android scroll android-arrayadapter contacts sectionindexer


    【解决方案1】:

    据我所知,您的实现看起来还不错。我认为有两种可能:

    1. 您的 Contact.getSection() 方法没有返回正确的值。
    2. 实际上,您的索引器工作正常,但对您来说似乎工作异常。如果屏幕顶部的项目(不是列表中的)与您的部分索引匹配,则它可以正常工作,因为它始终是决定您在列表中的实际位置的最顶部的项目。因此,如果索引器显示字母“B”并且屏幕上可见的第一个联系人以“B”开头,这是正确的(尽管大多数当前可见的联系人可能以“C”开头,这可能会导致错误的假设位于“C”部分)。

    如果您能保证这两件事都是正确的,请提供错误的屏幕截图和您的alphaIndexer 映射的print


    虽然与您的问题没有直接关系,但您应该重新设计 getSectionForPosition() 的实现(原文如此!),因为返回一个常量可能会导致滑动列表时滚动条的位置不正确(请参阅 here 了解更多信息信息)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-06
      • 1970-01-01
      • 2014-08-06
      相关资源
      最近更新 更多