SectionIndexer 在模拟联系人应用程序中移动
SectionIndexer shifted in mock contacts app
编辑:post 底部的解决方案。
我正在为 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);
}
据我所知,您的实施看起来还不错。我觉得有两种可能:
- 您的
Contact.getSection()
方法没有 return 正确的值。
- 实际上您的索引器工作正常,但它对您来说似乎工作起来很奇怪。如果屏幕最顶部(不是列表)的项目与您的部分索引匹配,则它可以正常工作,因为它始终是最顶部的项目,决定了您在列表中的实际位置。因此,如果索引器显示字母 'B' 并且屏幕上可见的第一个联系人以 'B' 开头,则它是正确的(尽管大多数当前可见的联系人可能以 'C' 开头,这可能会导致错误假设在 'C').
部分
如果您能确保这两件事都是正确的,请提供错误的屏幕截图和 print
您的 alphaIndexer
映射。
虽然与您的问题没有直接关系,但您应该重新实现 getSectionForPosition()
(原文如此!),因为 return 常量可能会导致滑动时滚动条的位置不正确您的列表(有关详细信息,请参阅 )。
编辑:post 底部的解决方案。
我正在为 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);
}
据我所知,您的实施看起来还不错。我觉得有两种可能:
- 您的
Contact.getSection()
方法没有 return 正确的值。 - 实际上您的索引器工作正常,但它对您来说似乎工作起来很奇怪。如果屏幕最顶部(不是列表)的项目与您的部分索引匹配,则它可以正常工作,因为它始终是最顶部的项目,决定了您在列表中的实际位置。因此,如果索引器显示字母 'B' 并且屏幕上可见的第一个联系人以 'B' 开头,则它是正确的(尽管大多数当前可见的联系人可能以 'C' 开头,这可能会导致错误假设在 'C'). 部分
如果您能确保这两件事都是正确的,请提供错误的屏幕截图和 print
您的 alphaIndexer
映射。
虽然与您的问题没有直接关系,但您应该重新实现 getSectionForPosition()
(原文如此!),因为 return 常量可能会导致滑动时滚动条的位置不正确您的列表(有关详细信息,请参阅