列表视图对齐项目

Mar*_*vre 16 android listview

我正在使用ListView创建图片列表,照片的大小可以在屏幕上显示2到3张照片.

我遇到的问题是,当用户停止滚动显示可见列表的第一项将捕捉到屏幕顶部时,例如,如果滚动结束并显示第一张图片的一小部分,我们向下滚动列表以便图片始终完全显示,如果显示的是大部分图片,我们将列表向上滚动,以便下一张图片完全可见.

有没有办法在listview中实现这个?

Mar*_*vre 26

我已经找到了一种方法来做这个只是听滚动并通过实现ListView.OnScrollListener滚动结束时更改位置

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
    switch (scrollState) {
    case OnScrollListener.SCROLL_STATE_IDLE:
        if (scrolling){
            // get first visible item
            View itemView = view.getChildAt(0);
            int top = Math.abs(itemView.getTop()); // top is a negative value
            int bottom = Math.abs(itemView.getBottom());
            if (top >= bottom){
                ((ListView)view).setSelectionFromTop(view.getFirstVisiblePosition()+1, 0);
            } else {
                ((ListView)view).setSelectionFromTop(view.getFirstVisiblePosition(), 0);
            }
        }
        scrolling = false;
        break;
    case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
    case OnScrollListener.SCROLL_STATE_FLING:
        Log.i("TEST", "SCROLLING");
        scrolling = true;
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

变化不是那么顺利但是有效.

  • 这样做的两个问题:1)smoothScrollToPosition将导致上述逻辑检测另一个滚动并进入一个抖动循环 - 您可以通过删除SCROLL_STATE_FLING的情况来避免这种情况,但我不确定这是否是一个很好的修复.2)smoothScrollToPosition没有正确对齐事物,至少与我的列表对齐.它将指定项目的顶部滚动到列表视图顶部上方15个像素,而不是像setSelection/setSelectionFromTop那样正确对齐事物. (2认同)

小智 5

利用来自@nininho解决方案的几个想法,我得到了我的listview以顺利滚动而不是突然转向该项目.需要注意的是,我只在带有文本的基本ListView中在Moto X上测试了这个解决方案,但它在设备上运行良好.尽管如此,我对此解决方案充满信心,并鼓励您提供反馈.

listview.setOnScrollListener(new OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            // TODO Auto-generated method stub
            if (scrollState == SCROLL_STATE_IDLE) {
                View itemView = view.getChildAt(0);
                int top = Math.abs(itemView.getTop());
                int bottom = Math.abs(itemView.getBottom());
                int scrollBy = top >= bottom ? bottom : -top;
                if (scrollBy == 0) {
                    return;
                }
                smoothScrollDeferred(scrollBy, (ListView)view);
            }
        }

        private void smoothScrollDeferred(final int scrollByF,
                final ListView viewF) {
            final Handler h = new Handler();
            h.post(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    viewF.smoothScrollBy(scrollByF, 200);
                }
            });
        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            // TODO Auto-generated method stub

        }
    });
Run Code Online (Sandbox Code Playgroud)

我推迟平滑滚动的原因是因为在我的测试中,直接调用状态改变回调的smoothScrollBy方法实际上有滚动问题.此外,我没有预见到一个经过充分测试的强大解决方案,并且在下面的解决方案中,我根本没有任何状态.此解决方案尚未在Google Play商店中使用,但应作为一个很好的起点.