Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
207 views
in Technique[技术] by (71.8m points)

expandablelistview - android fastScroll only covers part of the list

I have a class which implements expandable list activity.
In the XML code (or I can do it in java), I set fastScrollEnabled to true. This does in deed enable fast scroll. BUT fast scroll only works in the top portion of the list. Like I can use the fastscroll thumb bar to scroll the whole list but only works in the top section of the scroll bar. It's not proportionate to the entire list. I can drag the thumb bar to the bottom of the list but it does no scrolling since the listview is already scrolled to the bottom due to the odd behaviour of it only working in the top portion of the list.
Confusing I know, I can try to clarify more if needed....

I do implement a custom BaseExpandableListAdapter.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've just found a workaround to prevent the system to display this wrong behaviour.

There are two scenarios which use different code for the SectionIndexer to work.

The first scenario is the case that you use the FastScrollbar-Thumb to navigate to the next section. Assuming that the groups are your sections the overriden methods for implementing the SectionIndexer would look like that:

@Override
public int getPositionForSection(int section) {
    return section;
}

// Gets called when scrolling the list manually
@Override
public int getSectionForPosition(int position) {
    return ExpandableListView.getPackedPositionGroup(
               expandableListView
                   .getExpandableListPosition(position));
}

The second scenario is the case that you scroll the list manually and the fast scrollbars move according to the sections, not to all items. The code therefore looks like that:

@Override
public int getPositionForSection(int section) {
    return expandableListView.getFlatListPosition(
               ExpandableListView.getPackedPositionForGroup(section));
}

// Gets called when scrolling the list manually
@Override
public int getSectionForPosition(int position) {
    return ExpandableListView.getPackedPositionGroup(
               expandableListView
                   .getExpandableListPosition(position));
}

As one can see these two behaviours can not play together without further adoption.

The workaround to make it both work is to catch the case when someone is scrolling per hand (i.e. scrolling via touch). This can be done with implementing the OnScrollListener interface with the adapter class and set it onto the ExpandableListView:

public class MyExpandableListAdapter extends BaseExpandableListAdapter 
                 implements SectionIndexer, AbsListView.OnScrollListener {

    // Your fields here
    // ...
    private final ExpandableListView expandableListView;
    private boolean manualScroll;

    public MyExpandableListAdapter(ExpandableListView expandableListView
                                   /* Your other arguments */) {
        this.expandableListView = expandableListView;
        this.expandableListView.setOnScrollListener(this);
        // Other initializations
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        this.manualScroll = scrollState == SCROLL_STATE_TOUCH_SCROLL;
    }

    @Override
    public void onScroll(AbsListView view, 
                         int firstVisibleItem, 
                         int visibleItemCount, 
                         int totalItemCount) {}

    @Override
    public int getPositionForSection(int section) {
        if (manualScroll) {
            return section;
        } else {            
            return expandableListView.getFlatListPosition(
                       ExpandableListView.getPackedPositionForGroup(section));
        }
    }

    // Gets called when scrolling the list manually
    @Override
    public int getSectionForPosition(int position) {
        return ExpandableListView.getPackedPositionGroup(
                   expandableListView
                       .getExpandableListPosition(position));
    }

    // Your other methods
    // ...
}

That fixed the bug for me.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...