代码之家  ›  专栏  ›  技术社区  ›  Randy Sugianto 'Yuku'

在Android中按像素滚动列表视图

  •  7
  • Randy Sugianto 'Yuku'  · 技术社区  · 15 年前

    ListView 在安卓系统中,以像素为单位。例如,我想向下滚动列表10个像素(以便列表中的第一个项目隐藏其前10个像素行)。

    我以为那是显而易见的 scrollBy scrollTo ListView上的方法可以完成这项工作,但它们没有,而是错误地滚动整个列表(事实上 getScrollY 始终返回零,即使我已使用手指滚动列表。)

    5 回复  |  直到 15 年前
        1
  •  12
  •   Sam    13 年前

    支持的滚动列表的方式 ListView

    mListView.smoothScrollToPosition(position);

    http://developer.android.com/reference/android/widget/AbsListView.html#smoothScrollToPosition(int)

    但是,由于您特别提到要垂直偏移视图,因此必须调用:

    mListView.setSelectionFromTop(position, yOffset);

    http://developer.android.com/reference/android/widget/ListView.html#setSelectionFromTop(int,%20int)

    smoothScrollByOffset(yOffset) . 但是,它仅在API上受支持>=11

    http://developer.android.com/reference/android/widget/ListView.html#smoothScrollByOffset(int)

        2
  •  10
  •   enl8enmentnow    9 年前

    trackMotionScroll

    public class FutureListView {
    
        private final ListView mView;
    
        public FutureListView(ListView view) {
            mView = view;
        }
    
        /**
         * Scrolls the list items within the view by a specified number of pixels.
         *
         * @param y the amount of pixels to scroll by vertically
         */
        public void scrollListBy(int y) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                mView.scrollListBy(y);
            } else {
                // scrollListBy just calls trackMotionScroll
                trackMotionScroll(-y, -y);
            }
        }
    
        private void trackMotionScroll(int deltaY, int incrementalDeltaY) {
            try {
                Method method = AbsListView.class.getDeclaredMethod("trackMotionScroll", int.class, int.class);
                method.setAccessible(true);
                method.invoke(mView, deltaY, incrementalDeltaY);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            };
        }
    }
    
        3
  •  3
  •   Community CDub    12 年前

    ListView 子类。它可以很容易地进行调整,以便在活动代码中使用。

    getListItemsHeight() 返回列表的总像素高度,并用每个项目的垂直像素偏移量填充数组。虽然这些信息是有效的, getListScrollY() 返回当前垂直像素滚动位置,然后 scrollListToY() 如果列表的大小或内容发生变化, getListItemsHight() 必须再打一次电话。

    private int m_nItemCount;
    private int[] m_nItemOffY;
    
    private int getListItemsHeight() 
    {  
        ListAdapter adapter = getAdapter();  
        m_nItemCount = adapter.getCount();
        int height = 0;
        int i;
    
        m_nItemOffY = new int[m_nItemCount];
    
        for(i = 0; i< m_nItemCount; ++i){ 
            View view  = adapter.getView(i, null, this);  
    
            view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                        MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));  
    
            m_nItemOffY[i] = height;
            height += view.getMeasuredHeight();
        }  
    
        return height;  
    }  
    
    private int getListScrollY()
    {
        int pos, nScrollY, nItemY;
        View view;
    
        pos = getFirstVisiblePosition();
        view = getChildAt(0);
        nItemY = view.getTop();
        nScrollY = m_nItemOffY[pos] - nItemY;
    
        return nScrollY;
    }
    
    private void scrollListToY(int nScrollY)
    {
        int i, off;
    
        for(i = 0; i < m_nItemCount; ++i){
            off = m_nItemOffY[i] - nScrollY;
            if(off >= 0){
                setSelectionFromTop(i, off);
                break;
            }
        }
    }
    
        4
  •  1
  •   ddg    8 年前

    目前,ListViewCompat可能是一个更好的解决方案。

    android.support.v4.widget.ListViewCompat.scrollListBy(@NonNull ListView listView, int y)
    
        5
  •  0
  •   Maurice    9 年前

    如果你想按像素移动,你可以用这个

    public void scrollBy(ListView l, int px){
        l.setSelectionFromTop(l.getFirstVisiblePosition(),l.getChildAt(0).getTop() - px);
    }