1

I am working on a ListActivity that has a inner class that is a child of SimpleAdapter that implements 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;
    }
}

The activity is receives a JSON object in a separate AysncTask. This object is made up of various JSONArrays whose keys are first letter of the item the items of the array. So, the array is made up of a bunch of items that begin with the letter "B". Therefore, that JSONArray's key is "B".

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

The object does not necessarily have all of the letters of the alphabet. I am also aware that order is not guaranteed with JSONObjects so I sort them.
List> maps = new ArrayList>(); ArrayList sections = new 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);

The problem I am having is with FastScroll. I have everything working for the most part. The list is grouped by first letter and when using FastScroll the letter appears in the popup and goes to the correct group. The issue is when I let go of the FastScroll after going to the desired section the FastScroll "Jumps" to a random part of the list. It doesn't stay in the location where I let go of it. I think it is going to an arbitrary place in the section because I do not have the SectionIndexer implemented right. I think the problem is with this method.

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

I am just not sure how to implement the SectionIndexer methods properly...

4

2 回答 2

1

TL;DR First answer can't be correct. If you need a sample implementation of the getSectionForPosition method, see here.

You're right, it looks like a problem with your implementation of getSectionForPosition. The answer provided so far can't be correct because you need to return the index of the section a certain position is related to and not the position a section is related to (that is what you getPositionForSection method should do).

So you should rework your getSectionForPosition method (again). You need a valid mapping for every position to a section. Documentation says:

Given a position within the adapter, returns the index of the corresponding section within the array of section objects.

If you need an example of how to build such a mapping, see here. Implemented correctly, it will solve the problem of a jumping scrollbar and instead will position it properly.

于 2015-03-31T12:07:44.820 回答
-2

I saw many time getSectionForPosition implemented in the same way like 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);
    }
于 2011-07-19T21:50:26.130 回答