Pinned groups in ExpandableListView

前端 未结 5 511
Happy的楠姐
Happy的楠姐 2020-12-24 04:10

Is there a standard way to pin group item to the top of screen while scrolling group\'s items. I saw similar examples with ListView. What interfaces should I implement or wh

5条回答
  •  感动是毒
    2020-12-24 04:24

    I've tried to implement Homo Incognito's solution and encounter the same problem of pinned header not being clickable.

    The culprit seems to be the ListView itself consuming all the click event thus not passing any to our 'augmented' header view. So you could try digging in ExpandableListView's click handling implementation, which is quite a mess considering its inheritance all the way up to AdapterView.

    Instead of trying to highjack the click from ListView, I try circumnavigating such issue by simulating the header click from the list item underneath it. To do so, you need to implement the onChildClick to first see whether the position of the clicked item is underneath the pinned header, if so, then you can relay the click to the true header, if not, then just process the click for that item normally.



    In the example below, when the clicked item is underneath the pinned header, I simply made the ListView scrolling to the true header, thus replacing the 'augmented' pinned header with the true header, and the user can take further action from there, e.g. collapsing the group.

    Note that such usability flow works only if you don't have any clickable view on the header items, otherwise you will have to do all the click relay and mapping between the pinned virtual header and the true header yourself with onInterceptTouchEvent.


    Following Homo Incognito's Code, in PinnedHeaderExpListView.java add the following method:

    public int getHeaderViewHeight(){
            return mHeaderViewHeight;
        }
    

    in the activity onCreate, append the following:

    elv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
    
            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                    int groupPosition, int childPosition, long id) {
    
                // we need to obtain the relative y coordinate of the child view, 
                // not its clicked subview, thus first we try to calculate its true index
                long packedPos = ExpandableListView.getPackedPositionForChild(groupPosition, childPosition);
                int viewPos = elv.getFlatListPosition(packedPos) - elv.getFirstVisiblePosition(); 
                View childView = parent.getChildAt(viewPos); // got it
    
    
                if (childView.getTop() < elv.getHeaderViewHeight()*.75){
                     // if the clicked child item overlaps more than 25%
                     //  of pinned header, consider it being underneath
                     long groupPackedPos = ExpandableListView.getPackedPositionForGroup(groupPosition);
                     int groupFlatPos = elv.getFlatListPosition(groupPackedPos);
                     elv.smoothScrollToPosition(groupFlatPos);
                }
                return true;
            }
        });
    

提交回复
热议问题