ScrollView 内不可滚动的 ListView

Posted

技术标签:

【中文标题】ScrollView 内不可滚动的 ListView【英文标题】:Non-scrollable ListView inside ScrollView 【发布时间】:2013-09-19 17:36:57 【问题描述】:

我正在尝试制作这样的布局:

问题是我不希望ListViews 可滚动。 我希望它们尽可能高,并使整个屏幕可滚动。如果我将ListView 的高度设置为wrap_content,那是行不通的。使它工作的唯一方法是设置一个特定的高度 - 但我不知道ListView 中有多少项目。

我知道我不应该将ListView 放在ScrollView - 但我不希望ListView 可滚动,只是为了显示所有项目。

也许有更好的方法让它发挥作用?

【问题讨论】:

【参考方案1】:

您创建不可滚动的自定义 ListView

public class NonScrollListView extends ListView 

    public NonScrollListView(Context context) 
        super(context);
    
    public NonScrollListView(Context context, AttributeSet attrs) 
        super(context, attrs);
    
    public NonScrollListView(Context context, AttributeSet attrs, int defStyle) 
        super(context, attrs, defStyle);
    
    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
            int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
                    Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
            ViewGroup.LayoutParams params = getLayoutParams();
            params.height = getMeasuredHeight();    
    

在您的布局资源文件中

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:fadingEdgeLength="0dp"
    android:fillViewport="true"
    android:overScrollMode="never"
    android:scrollbars="none" >

    <RelativeLayout
        android:layout_
        android:layout_ >

        <!-- com.Example Changed with your Package name -->

        <com.Example.NonScrollListView
            android:id="@+id/lv_nonscroll_list"
            android:layout_
            android:layout_ >
        </com.Example.NonScrollListView>

        <RelativeLayout
            android:layout_
            android:layout_
            android:layout_below="@+id/lv_nonscroll_list" >

            <!-- Your another layout in scroll view -->

        </RelativeLayout>
    </RelativeLayout>

</ScrollView>

在 Java 文件中

创建你的 customListview 对象而不是 ListView 喜欢: NonScrollListView non_scroll_list = (NonScrollListView) findViewById(R.id.lv_nonscroll_list);

【讨论】:

当将其交换到现有代码库中时,很可能在添加新类后只需要修改 XML;大多数将实例转换为(ListView) 的现有引用仍然可以正常工作。 @DEV 请详细说明您需要什么类型的布局 @Dedaniyahirenkumar,当android显示包含NonScrollListView的布局时,父ScrollView滚动到NonScrollListView的顶部,而不是ScrollView的顶部。 (用户必须向上滚动到NonScrollListView 之前的ScrollView 内容。)EXACTLYAT_MOST 测量模式以及传递给makeMeasureSpec() 的任何整数高度都会发生这种情况 @Dedaniyahirenkumar,但是,如果测量模式切换到 UNSPECIFIED,父 ScrollView 将保持滚动 Y=0(预期行为)。但是,显然NonScrollListView 在这种情况下不会显示其全部内容。 这就是我要寻找的东西,非常感谢 Dedaniya Hiren 先生 它就像一个魅力 :)【参考方案2】:

根本不需要使用listview

如果您真的考虑过,在您的情况下,listview 可以替换为 LinearLayoutAdapter 是相同的,但是不要将适配器与 listview 连接,只需在数据的 for 循环中调用适配器的 getView 函数,并将检索到的视图添加到垂直 linearlayout

但是,仅当列表中有少量项目并且这些项目的显示表示不占用大量内存时,才建议使用此方法。

【讨论】:

我使用线性布局而不是列表视图,它可以工作,但没有看到没有空间的项目!我在父级中使用线性布局 LinearLayout 不是 ListView 的公平替代品,当您想利用 AbsListView.CHOICE_MODE_MULTIPLE_MODAL 背后的优点时 - 为了避免重新发明***,请参阅 NonScrollListView 解决方案 我认为将 ListView 替换为 LinearLayout 似乎是合乎逻辑的,但您也会失去 ListView 固有的回收能力。尝试拥有一个 LinearLayout 并通过在其中填充大量视图来动态为其充电。垃圾收集器会发疯【参考方案3】:

做到这一点的最佳方法(2017 年) 是使用 RecyclerViewNestedScrollView

无需破解,开箱即用,如您所愿。

【讨论】:

虽然这是一个不错的解决方案,但我认为这不是 OP 想要的 The problem is that I don't want the ListViews to be scrollable【参考方案4】:

好吧,有一个很酷的 Android 人,名叫 Mark Murphy,又名 CommonsWare,他构建了一个非常有用的组件,名为 CWAC Merge Adapter,让您可以做您需要的事情。您需要动态添加视图,而不是从 XML 中添加;但考虑到您的简单用户界面,这应该不是问题。当我不知道应该滚动哪种数据时,我会将它用于此类情况。

如果您不想使用它(可能出于许可原因),您可以在其中拥有一个列表视图(而不是那两个连续的列表视图)并覆盖 getItemViewsCountgetItemViewTypegetView为了给出上述布局。如果您在 Google 上搜索 android listview different rows,您会发现有用的信息。例如this link,或this one。

但是,我会选择合并适配器。

【讨论】:

谢谢。问题是我希望 ImageView 和 TextView 是可滚动的 - 如果我向下滚动它们会向上并且 ListView 中的项目会出现。 然后使用合并适配器并在其中添加 ImageView 和 TextView。即使有多个列表类型,您也可以通过将 ImageView 和 TextView 的视图类型设置为 1 和 2 来做同样的事情。对于其余类型,您可以有 3 和 4。【参考方案5】:

如果可以计算您的项目高度/宽度,我有一个简单的解决方案......您只需要创建 ListView 的父线性布局,然后从 Java 中固定父高度。

假设您需要设计这个视图...现在父布局大小是从 java 定义的...

final LinearLayout parent=(LinearLayout)findViewById(R.id.parent);
final ListView  listview=(ListView)findViewById(R.id.listview);
parent.setLayoutParams(new LinearLayout.LayoutParams(parent.getLayoutParams().width, dpToPx( number_of_item_in_list * per_item_size_in_dp )));
//number_of_item_in_list is list side ~ listArray.size();
//per_item_size_in_dp = calculate item size in dp. Ex: 80dp

public static int dpToPx(int dp)

    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);

就是这样:)

【讨论】:

【参考方案6】:

选择你想要滚动的ListView,然后添加方法'setOnTouchListener'让系统自动在ListView中插入滚动

final ListView listview = (ListView) findViewById(R.id.list);


    listview.setOnTouchListener(new ListView.OnTouchListener()
    
        @Override
        public boolean onTouch(View v, MotionEvent event)
        
            int action = event.getAction();
            switch (action)
            
                case MotionEvent.ACTION_DOWN:
                    // Disallow ScrollView to intercept touch events.
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                    break;

                case MotionEvent.ACTION_UP:
                    // Allow ScrollView to intercept touch events.
                    v.getParent().requestDisallowInterceptTouchEvent(false);
                    break;
            

            // Handle ListView touch events.
            v.onTouchEvent(event);
            return true;
        
    );
    listview.setClickable(true);

希望对你有用

【讨论】:

【参考方案7】:

    如何在scrollView中滚动listView

    listViewName.setOnTouchListener(new ListView.OnTouchListener() 
      @Override
      public boolean onTouch(View v, MotionEvent event) 
        int action = event.getAction();
        switch (action) 
          case MotionEvent.ACTION_DOWN:
            // Disallow ScrollView to intercept touch events.
            v.getParent().requestDisallowInterceptTouchEvent(true);
            break;
          case MotionEvent.ACTION_UP:
            // Allow ScrollView to intercept touch events.
            v.getParent().requestDisallowInterceptTouchEvent(false);
            break;
        
        // Handle ListView touch events.
        v.onTouchEvent(event);
        return true;
      
    );
    listViewName.setClickable(true);
    

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于ScrollView 内不可滚动的 ListView的主要内容,如果未能解决你的问题,请参考以下文章

滚动视图内的不可滚动的tableview

ScrollView 中的图像不可滚动

可滚动父版面内的不可滚动ListView

为啥孩子的 Kivy ScrollView 孩子不可滚动?

带有 UIControl/UIButton 子视图的 ScrollView/TableView 在 iOS 8 下不可滚动

滚动时在 UIScrollView 内更新 UITextView 会使 scrollView 停止滚动