【问题标题】:ListView inside a ScrollView [duplicate]ScrollView中的ListView [重复]
【发布时间】:2011-03-24 05:06:41
【问题描述】:

可能重复:
Listview inside ScrollView is not scrolling on Android

我在ScrollView 中有一个ListView,问题是ScrollView 正在滚动,但ListView 不滚动。我认为这是因为ScrollView 而发生的。有人有这个问题的解决方案吗?

【问题讨论】:

标签: android listview scrollview


【解决方案1】:

ListViews 具有内置的滚动功能。将其封装在任何其他布局中,例如 LinearLayoutRelativeLayout

【讨论】:

    【解决方案2】:

    我需要在滚动视图中包含一个列表视图,以防止整个屏幕过长。这允许您必须设置列表上显示的项目数,而其余的将滚动。

    我在我的应用程序中使用了以下类,到目前为止它似乎工作得很好。

     public class NestedListView extends ListView implements OnScrollListener,
            OnTouchListener {
        private int listViewTouchAction;
        private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 4;
    
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
        }
    
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
                if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
                    scrollBy(0, -1);
                }
            }
        }
    
        public NestedListView(Context context, AttributeSet attrs) {
            super(context, attrs);
            listViewTouchAction = -1;
            setOnScrollListener(this);
            setOnTouchListener(this);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int newHeight = 0;
            final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);
            if (heightMode != MeasureSpec.EXACTLY) {
                ListAdapter listAdapter = getAdapter();
                if (listAdapter != null && !listAdapter.isEmpty()) {
                    int listPosition = 0;
                    for (listPosition = 0; listPosition < listAdapter.getCount()
                            && listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++) {
                        View listItem = listAdapter.getView(listPosition, null,
                                this);
                        listItem.measure(widthMeasureSpec, heightMeasureSpec);
                        newHeight += listItem.getMeasuredHeight();
                    }
                    newHeight += getDividerHeight() * listPosition;
                }
                if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize)) {
                    if (newHeight > heightSize) {
                        newHeight = heightSize;
                    }
                }
            } else {
                newHeight = getMeasuredHeight();
            }
            setMeasuredDimension(getMeasuredWidth(), newHeight);
        }
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            listViewTouchAction = event.getAction();
            if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
                if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
                    scrollBy(0, 1);
                }
            }
            return false;
        }
    }
    

    【讨论】:

    • 这个解决方案的问题是它消耗了大量的 CPU 资源。在 onMeasure 方法中,您要求 listadapter 重新创建您要求的每个视图,这将使整个应用程序非常慢。我认为您应该缓存您要求的视图,并且仅在它们无效时重新创建它们。
    • 虽然我没有注意到这个解决方案在我的 Atrix 上存在任何问题,但我确信它可能是旧设备上的问题。
    【解决方案3】:

    使用下面的方法,尽情享受吧!

        private void setListViewScrollable(final ListView list) {
        list.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                listViewTouchAction = event.getAction();
                if (listViewTouchAction == MotionEvent.ACTION_MOVE)
                {
                    list.scrollBy(0, 1);
                }
                return false;
            }
        });
        list.setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view,
                    int scrollState) {
            }
    
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {
                if (listViewTouchAction == MotionEvent.ACTION_MOVE)
                {
                    list.scrollBy(0, -1);
                }
            }
        });
    }
    

    listViewTouchAction 是一个全局整数值。 如果可以换行

    list.scrollBy(0, 1);
    

    还有其他的请与我们分享。

    【讨论】:

      【解决方案4】:

      您不应该在 ScrollView 中嵌套 ListView。

      如果您尝试将其他视图与 ListView 一起滚动,您可以查看this answer

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-06
        • 2020-02-21
        • 2013-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-01
        • 1970-01-01
        相关资源
        最近更新 更多