Android Grouped Suspended List Implementation

Posted by Jeannie109 on Sat, 06 Jul 2019 20:15:07 +0200

* Grouping lists is encountered during App development, and lists want groupings to float at the top of lists while they are sliding.The specific effect diagram is as follows

The implementation of a grouped floating list is http://blog.csdn.net/u010335298/article/details/51150346 On the basis of this, corresponding improvements have been made.

One, Grouped Suspended List Target

  • Rewrite ListView (SectionPinListView) to implement grouped floating lists without breaking all the original ListView functionality.
  • Rewrite BaseAdapter (SectionPinAdapter) to try to override the burden of BaseAdapter.
  • For ListView pull-up refresh, group suspension still works when the drop-down loads more.
  • SectionPinListView can set either an overridden SectionPinAdapter or not, and if a SectionPinAdapter is not overridden, there is no effect of group suspension.

Two, Grouped Suspended List Code

To achieve a grouped floating list, you need to know which grouping is currently suspended at the top whenever the ListView scrolls, and then rewrite the dispatchDraw() method of ListView to draw the grouped View at the top of the ListView.There are two things to sum up: one scrolls to get the grouped View to be suspended, and the second draws the View to the top.

  • The ListView scrolls to get the View to suspend:
    Now that you get a view to float while scrolling, you have to listen for the onScroller event and process it inside onScroll (). The floating View here is also a sub-View inside ListView. There is a way to get the View inside the Adapter. Know that the position in the adapter is done, paste the implementation directly belowCode.
    /**
     * @param absListView      ListView
     * @param firstVisibleItem First list item ID currently visible (starting at 0)
     * @param visibleItemCount Number of list items that are currently visible (less than half, including header views and footer views)
     * @param totalItemCount   List items are always (header count + adapter count + footer count)
     */
    @Override
    public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (mScrollListener != null) {
            mScrollListener.onScroll(absListView, firstVisibleItem, visibleItemCount, totalItemCount);
        }
        if (getAdapter() != null && !(getAdapter() instanceof SectionPinAdapter)) {
            return;
        }
        int headerViewCount = getHeaderViewsCount();
        if (getAdapter() == null || !mSectionPinEnable || firstVisibleItem < headerViewCount) {
            /**
             * The first section hasn't come out yet
             */
            mViewSectionPin = null;
            mSectionPinOffset = 0f;
            mSectionPinAdapterPosition = -1;
            for (int i = 0; i < visibleItemCount; i++) {
                View view = getChildAt(i);
                if (view != null) {
                    view.setVisibility(VISIBLE);
                }
            }
            return;
        }
        if (getAdapter().getCount() <= 0) {
            return;
        }
        int adapterFirstVisibleItem = firstVisibleItem - headerViewCount;
        int pinViewAdapterPosition = getPinViewAdapterPosition(adapterFirstVisibleItem);
        if (pinViewAdapterPosition != -1 && mSectionPinAdapterPosition != pinViewAdapterPosition) {
            /**
             * pin view Replaced
             */
            mViewSectionPin = getSectionPinView(pinViewAdapterPosition);
            ensurePinViewLayout(mViewSectionPin);
        }
        if (mViewSectionPin == null) {
            return;
        }

        mSectionPinOffset = 0f;
        /**
         * Traverse all visible views
         */
        for (int index = 0; index < visibleItemCount; index++) {
            int adapterPosition = index + adapterFirstVisibleItem;
            /**
             * Determine if it is a section
             */
            SectionPinAdapter adapter = (SectionPinAdapter) getAdapter();
            if (adapter.isSection(adapterPosition)) {
                View sectionView = getChildAt(index);
                int sectionTop = sectionView.getTop();
                int pinViewHeight = mViewSectionPin.getHeight();
                sectionView.setVisibility(VISIBLE);
                if (sectionTop < pinViewHeight && sectionTop > 0) {
                    mSectionPinOffset = sectionTop - pinViewHeight;
                } else if (sectionTop <= 0) {
                    sectionView.setVisibility(INVISIBLE);
                }

            }
        }
        invalidate();
    }
  • Grouped Suspended Views are drawn at the top of the ListView:
    draw out of ListView after you have the View to suspend.
    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);

        if (getAdapter() == null || !(getAdapter() instanceof SectionPinAdapter) || mViewSectionPin == null || !mSectionPinEnable) {
            return;
        }
        int saveCount = canvas.save();
        /**
         * canvas vertical translation
         */
        canvas.translate(0, mSectionPinOffset);
        canvas.clipRect(0, 0, getWidth(), mViewSectionPin.getMeasuredHeight()); // needed
        mViewSectionPin.draw(canvas);
        canvas.restoreToCount(saveCount);
    }

Finally, paste the code directly, and it may look more coherent and detailed
https://github.com/tuacy/SectionPin

Topics: less github