c# - 同一个 RelativeLayout 中的多个 ListView

标签 c# android listview mono scroll

我有一个正在尝试开发的应用程序。在应用程序的一种布局中,我有多个 ListView 组件。大纲如下所示:

<ScrollView>
   <RelativeLayout>
      <TextView />
      <TextView />
      <ListView />
      <ListView />
      <ListView />
      <Button />
   </RelativeLayout>
</ScrollView>

三个独立的 ListView 组件列出了 3 种不同类型的项目。我的问题来了,当用 ScrollView 封装时,ListView 决定每个只显示 1 个项目,然后落入它们的滚动行为。我更喜欢让他们显示所有项目,并让 ScrollView 进行滚动。这可能吗?

我在这里阅读了一些其他问题,似乎惯例是不在每个布局中使用多个 ListView。如果可能的话,我宁愿完成这项工作,因为列出的 3 个单独项目是相关的,并且一起显示很有意义。

最佳答案

ListView 主要是为滚动而设计的。 ListView使用回收机制,当item数量较多(相对于屏幕尺寸)时滚动更流畅。如果您希望您的 ListView 一次显示所有项目,您实际上并不需要 ListView。请改用 LinearLayout。我猜你正在使用列表适配器来填充你的列表。因此,您可以通过使用自定义 setAdapter() 方法来扩展 LinearLayout 并利用您的适配器。这是我为不可滚动列表创建的类。

public class NonScrollableListView extends LinearLayout {
    private BaseAdapter mAdapter;
    private AdapterDataSetObserver mDataSetObserver;

    public NonScrollableListView(Context context) {
        super(context);
    }

    public NonScrollableListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NonScrollableListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if(mAdapter != null && mDataSetObserver != null){
            mDataSetObserver = new AdapterDataSetObserver();
            mAdapter.registerDataSetObserver(mDataSetObserver);
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if(mAdapter != null && mDataSetObserver != null){
            mAdapter.unregisterDataSetObserver(mDataSetObserver);
        }
    }

    public void setAdapter(BaseAdapter adapter) {
        this.mAdapter = adapter;

        if(mAdapter != null && mDataSetObserver != null){
            mAdapter.unregisterDataSetObserver(mDataSetObserver);
        }

        mDataSetObserver = new AdapterDataSetObserver();
        mAdapter.registerDataSetObserver(mDataSetObserver);

        mDataSetObserver.onChanged();
    }

    private void fillChildViews(){
        if(mAdapter != null){
           int requiredChilrenCount = mAdapter.getCount();
           int currentChildrenCount = getChildCount();

            for(int i = 0; i < requiredChilrenCount; i++){
                View nextChild = getChildAt(i);
                View nextChildToAdd = mAdapter.getView(i, nextChild, this);
                nextChildToAdd.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

                if(nextChild == null){
                    addView(nextChildToAdd);
                }
            }

           //Remove remaining child views if any
           for(int i = requiredChilrenCount; i < currentChildrenCount; i++){
               //The length of the children list changes so need to get it at each iteration
               removeViewAt(getChildCount() - 1);
           }
        }
        else{
            removeAllViews();
        }
    }

    private class AdapterDataSetObserver extends DataSetObserver{
        @Override
        public void onChanged() {
            fillChildViews();
        }
    }
}

您可以像使用 ListView 一样使用它。请注意,项目数量预计相对较少。否则您将遇到性能问题。

关于c# - 同一个 RelativeLayout 中的多个 ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13639569/

相关文章:

c# - 计算水平偏移以将 ListView 滚动到 SelectedItem 的中心

android - 如何更改选定/聚焦的 ListView 项目中的字体颜色?

c# - 在不创建新矩阵变换的情况下设置图像的布局变换

c# - 用户定义的类的对象/类数组失败

c# - build DAL。使用 EDM(来自数据库)

android - 安装 OpenGL ES 并为 android 编译代码

android - 向我的 Activity/fragment 添加绘图/绘画功能

java - 使用 Android 开发卡在 Eclipse 中的模拟器屏幕上?

android - 有没有办法从主要 Activity 中隐藏特定的 ListView 项目?

c# - 是否可以在.NET Core Web应用程序的任务管理器中设置显示名称?