Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9bf3c128 authored by Adam Powell's avatar Adam Powell
Browse files

ListView now tries to keep the position containing focused child views on-screen.

parent eb6d1310
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -4017,6 +4017,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
         * View type for this view, as returned by
         * {@link android.widget.Adapter#getItemViewType(int) }
         */
        @ViewDebug.ExportedProperty(mapping = {
            @ViewDebug.IntToString(from = ITEM_VIEW_TYPE_IGNORE, to = "ITEM_VIEW_TYPE_IGNORE"),
            @ViewDebug.IntToString(from = ITEM_VIEW_TYPE_HEADER_OR_FOOTER, to = "ITEM_VIEW_TYPE_HEADER_OR_FOOTER")
        })
        int viewType;

        /**
@@ -4025,6 +4029,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
         * been added to the list view and whether they should be treated as
         * recycled views or not.
         */
        @ViewDebug.ExportedProperty
        boolean recycledHeaderFooter;

        public LayoutParams(Context c, AttributeSet attrs) {
+36 −0
Original line number Diff line number Diff line
@@ -140,6 +140,9 @@ public class ListView extends AbsListView {
    // allocating these thingies too often.
    private final ArrowScrollFocusResult mArrowScrollFocusResult = new ArrowScrollFocusResult();

    // Keeps focused children visible through resizes
    private FocusSelector mFocusSelector;
    
    public ListView(Context context) {
        this(context, null);
    }
@@ -1017,6 +1020,39 @@ public class ListView extends AbsListView {
        return sel;
    }

    private class FocusSelector implements Runnable {
        private int mPosition;
        private int mPositionTop;
        
        public FocusSelector setup(int position, int top) {
            mPosition = position;
            mPositionTop = top;
            return this;
        }
        
        public void run() {
            setSelectionFromTop(mPosition, mPositionTop);
        }
    }
    
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if (getChildCount() > 0) {
            View focusedChild = getFocusedChild();
            if (focusedChild != null) {
                final int childPosition = mFirstPosition + indexOfChild(focusedChild);
                final int childBottom = focusedChild.getBottom();
                final int offset = Math.max(0, childBottom - (h - mPaddingTop));
                final int top = focusedChild.getTop() - offset;
                if (mFocusSelector == null) {
                    mFocusSelector = new FocusSelector();
                }
                post(mFocusSelector.setup(childPosition, top));
            }
        }
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Sets up mListPadding