FastScroll ведет себя странно с пользовательским адаптером ListAd, который реализует SectionIndexer

1

Я работаю над ListActivity, у которого есть внутренний класс, являющийся дочерним элементом SimpleAdapter, который реализует SectionIndexer.

class MySimpleAdapter extends SimpleAdapter implements SectionIndexer {

    HashMap<String, Integer> letters;
    Object[] sections;
    AlphabetIndexer alphaIndexer;
    public MySimpleAdapter(Context context, List<? extends Map<String, ?>> data,
            int resource, String[] from, int[] to, 
            HashMap<String, Integer> letters, Object[] sections) {
        super(context, data, resource, from, to);

        this.letters = letters;
        this.sections = sections;
    }

    @SuppressWarnings("unchecked")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            convertView = getLayoutInflater().inflate(R.layout.common_image_row1, null);
        }

        HashMap<String, Object> data = (HashMap<String, Object>) getItem(position);
        Integer idArtist = Integer.parseInt((String) data.get("idArtist"));

        convertView.setTag(idArtist);

        ((TextView) convertView.findViewById(R.id.item_name))
            .setText((String) data.get("sName"));

        ImageView image = (ImageView) convertView.findViewById(R.id.item_image);
        image.setTag((String) data.get("sImageUrl"));           
        image.setImageResource(R.drawable.default_artwork);

        ((TextView) convertView.findViewById(R.id.item_count))
            .setText((String) data.get("iSongs") + " Songs");

        if (!bScrolling) {
            new API.DownloadImagesTask().execute(image);
        }
        return convertView;
    }

    public int getPositionForSection(int section) {
        String letter = (String) sections[section];

        return letters.get(letter);

    }

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

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

Эта активность получает объект JSON в отдельной AysncTask. Этот объект состоит из различных JSONArrays, ключи которых являются первой буквой элемента, элементы массива. Таким образом, массив состоит из множества элементов, которые начинаются с буквы "B". Следовательно, ключ JSONArray - "B".

{
    B: ["ball", "buck", "bill"]
    C: ["charlie", "chuck", "chap"]
}

Объект не обязательно имеет все буквы алфавита. Я также знаю, что порядок не гарантируется с JSONObjects, поэтому я сортирую их.
List> maps = new ArrayList>(); Разделы ArrayList = новый ArrayList(); HashMap letters = new HashMap();

        String[] alphabet = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N"
                ,"O","P","Q","R","S","T","U","V","W","X","Y","Z"};
        int k = 0;
        for (int i = 0; i < alphabet.length; i++) {
            if (playlistArtists.optJSONArray(alphabet[i]) != null) {
                try {
                    JSONArray artists = playlistArtists.getJSONArray(alphabet[i]);
                    sections.add(alphabet[i]);

                    for (int j = 0; j < artists.length(); j++) {
                        JSONObject artist = (JSONObject) artists.get(j);
                        HashMap<String, String> map= new HashMap<String, String>();
                        map.put("idArtist", artist.getString("idArtist"));
                        map.put("sName", artist.getString("sName"));
                        map.put("sImageUrl", artist.getString("sImageUrl-thumb"));
                        map.put("iSongs", artist.getString("iSongs"));
                        maps.add(map);

                        letters.put(alphabet[i], k);
                        k++;
                    }
                } catch (JSONException e) {
                    Log.d(TAG,"JSONException in Music::GetMusicCatlog.doInBackground");
                    e.printStackTrace();
                }

            }
        }
        SimpleAdapter adapter = new MySimpleAdapter(Catalog.this, 
                maps,
                R.layout.common_image_row1,
                new String[] {"idArtist","sName", "sImageUrl", "iSongs" },
                new int[] {R.id.item_id, R.id.item_name, R.id.item_image, R.id.item_count }, 
                letters, 
                sections.toArray());
        setListAdapter(adapter);

У меня проблема с FastScroll. У меня есть все, что работает по большей части. Список сгруппирован по первой букве, и при использовании FastScroll письмо появляется во всплывающем окне и переходит в нужную группу. Проблема в том, что я отпустил FastScroll после перехода в нужный раздел FastScroll "Переходы" в случайную часть списка. Он не остается в том месте, где я его отпустил. Я думаю, что это будет произвольное место в этом разделе, потому что у меня нет правильного решения SectionIndexer. Я думаю, проблема связана с этим методом.

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

Я просто не знаю, как правильно реализовать методы SectionIndexer...

  • 0
    как sidenote: getPositionForSection () должен возвращать начальный индекс, а не последний индекс (который вы делаете). Таким образом, предполагая, что художники отсортированы по AZ, либо просмотрите массив художников в обратном порядке, либо добавьте индекс в hashmap для букв только в том случае, если этот ключ еще не существует (поэтому вы добавляете только первый индекс)
Теги:
listview
listadapter

2 ответа

-1
Лучший ответ

Я видел много раз, когда getSectionForPosition реализован так же, как getPositionForSection

    public int getPositionForSection(int section) {
        String letter = (String) sections[section];

        return letters.get(letter);
    }

    public int getSectionForPosition(int position) {
        String letter = (String) sections[position];

        return letters.get(letter);
    }
  • 0
    Я немного изменил ваш ответ, и это немного помогло. Это все еще не идеально, хотя. 'String letter = (String) section [position]' в getSectionForPosition (int position)
  • 0
    Да, ты прав, моя ошибка. Исправлено Спасибо.
Показать ещё 1 комментарий
1

TL; DR Первый ответ не может быть правильным. Если вам нужна примерная реализация метода getSectionForPosition, см. Здесь.

Вы правы, это похоже на проблему с вашей реализацией getSectionForPosition. Ответ, предоставленный до сих пор, не может быть правильным, потому что вам нужно вернуть индекс раздела, к которому относится определенная позиция, а не к позиции, к которой относится раздел (это то, что должен сделать метод getPositionForSection).

Поэтому вы должны переработать свой метод getSectionForPosition (снова). Для каждой позиции в разделе вам нужно иметь действительное сопоставление. Документация гласит:

Учитывая позицию внутри адаптера, возвращает индекс соответствующего раздела в массиве объектов раздела.

Если вам нужен пример построения такого сопоставления, см. Здесь. Реализовано правильно, оно решит проблему прыгающей полосы прокрутки и вместо этого разместит ее правильно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню