开发者

android fastScroll only covers part of the list

开发者 https://www.devze.com 2023-01-31 03:20 出处:网络
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

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.


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.


This is a bug in the fast scroller. It does not play well with ExpandableListView.

See my code.

(it also includes a work-around for some cases)

0

精彩评论

暂无评论...
验证码 换一张
取 消