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

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

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

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

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

【问题讨论】:

    标签: android android-listview scrollview


    【解决方案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_width="match_parent"
        android:layout_height="match_parent"
        android:fadingEdgeLength="0dp"
        android:fillViewport="true"
        android:overScrollMode="never"
        android:scrollbars="none" >
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
    
            <!-- com.Example Changed with your Package name -->
    
            <com.Example.NonScrollListView
                android:id="@+id/lv_nonscroll_list"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >
            </com.Example.NonScrollListView>
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                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】:
        1. 如何在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
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-01
        • 2013-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多