使用 ListAdapter 在 ScrollView 布局内填充 LinearLayout [英] Using a ListAdapter to fill a LinearLayout inside a ScrollView layout

查看:36
本文介绍了使用 ListAdapter 在 ScrollView 布局内填充 LinearLayout的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面临一个非常普遍的问题:我布置了一个活动,现在它应该在这个 ScrollView 中显示一些项目.这样做的正常方法是使用现有的 ListAdapter,将其连接到 ListViewBOOM 我会有我的项目列表.

I'm facing a very common problem: I layed out an activity and now it turns out it should display a few items within this ScrollView. The normal way to do that would be to use the existing ListAdapter, connect it to a ListView and BOOM I'd have my list of items.

但是您不应该将嵌套的 ListView 放置在 ScrollView 中,因为它会破坏滚动 - 甚至 Android Lint 也抱怨它.

BUT You should not place a nested ListView in a ScrollView as it screws up the scrolling - even Android Lint complains about it.

所以这是我的问题:

如何将 ListAdapter 连接到 LinearLayout 或类似的东西?

How do I connect a ListAdapter to a LinearLayout or something similar?

我知道这个解决方案不会针对很多项目进行扩展,但我的列表非常短(<10 个项目),因此并不真正需要重复使用视图.性能方面,我可以忍受将所有视图直接放入 LinearLayout.

I know this solution won't scale for a lot of items but my lists is very short (< 10 items) so reusage of views is not really needed. Performance wise I can live with placing all views directly into the LinearLayout.

我想出的一个解决方案是将我现有的活动布局放在 ListView 的 headerView 部分.但这感觉就像在滥用这种机制,所以我正在寻找更清洁的解决方案.

One solution I came up with would be to place my existing activity layout in the headerView section of the ListView. But this feels like abusing this mechanism so I'm looking for a cleaner solution.

想法?

更新:为了激发正确的方向,我添加了一个示例布局来展示我的问题:

UPDATE: In order to inspire the right direction I add a sample layout to show my problem:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/news_detail_layout"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical"
              android:visibility="visible">


    <ScrollView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="#FFF"
            >

        <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:orientation="vertical"
                android:paddingLeft="@dimen/news_detail_layout_side_padding"
                android:paddingRight="@dimen/news_detail_layout_side_padding"
                android:paddingTop="@dimen/news_detail_layout_vertical_padding"
                android:paddingBottom="@dimen/news_detail_layout_vertical_padding"
                >

            <TextView
                    android:id="@+id/news_detail_date"
                    android:layout_height="wrap_content"
                    android:layout_width="fill_parent"
                    android:gravity="center_horizontal"
                    android:text="LALALA"
                    android:textSize="@dimen/news_detail_date_height"
                    android:textColor="@color/font_black"
                    />

            <Gallery
                    android:id="@+id/news_detail_image"
                    android:layout_height="wrap_content"
                    android:layout_width="fill_parent"
                    android:paddingTop="5dip"
                    android:paddingBottom="5dip"
                    />

            <TextView
                    android:id="@+id/news_detail_headline"
                    android:layout_height="wrap_content"
                    android:layout_width="fill_parent"
                    android:gravity="center_horizontal"
                    android:text="Some awesome headline"
                    android:textSize="@dimen/news_detail_headline_height"
                    android:textColor="@color/font_black"
                    android:paddingTop="@dimen/news_detail_headline_paddingTop"
                    android:paddingBottom="@dimen/news_detail_headline_paddingBottom"
                    />

            <TextView
                    android:id="@+id/news_detail_content"
                    android:layout_height="wrap_content"
                    android:layout_width="fill_parent"
                    android:text="Here comes a lot of text so the scrollview is really needed."
                    android:textSize="@dimen/news_detail_content_height"
                    android:textColor="@color/font_black"
                    />

            <!---
                HERE I NEED THE LIST OF ITEMS PROVIDED BY THE EXISTING ADAPTER. 
                They should be positioned at the end of the content, so making the scrollview smaller is not an option.
            ---->                        

        </LinearLayout>
    </ScrollView>
</LinearLayout>

更新 2 我更改了标题以使其更易于理解(得到了反对票,哦!).

UPDATE 2 I changed the headline to make it easier to understand (got a downvote, doh!).

推荐答案

您可能应该手动将您的项目添加到 LinearLayout:

You probably should just manually add your items to LinearLayout:

LinearLayout layout = ... // Your linear layout.
ListAdapter adapter = ... // Your adapter.

final int adapterCount = adapter.getCount();

for (int i = 0; i < adapterCount; i++) {
  View item = adapter.getView(i, null, null);
  layout.addView(item);
}

编辑:当我需要显示大约 200 个非平凡的列表项时,我拒绝了这种方法,它非常慢 - Nexus 4 需要大约 2 秒才能显示我的列表",这是不可接受的.所以我转向了 Flo 的标题方法.它的运行速度要快得多,因为列表视图是在用户滚动时按需创建的,而不是在创建视图时创建.

EDIT: I rejected this approach when I needed to display about 200 non-trivial list items, it is very slow - Nexus 4 needed about 2 seconds to display my "list", that was unacceptable. So I turned to Flo's approach with headers. It works much faster because list views are created on demand when user scrolls, not at the time the view is created.

简历:手动添加视图到布局更容易编码(因此可能会减少移动部件和错误),但会遇到性能问题,所以如果你有 50 个或更多的视图,我建议使用标题方法.

Resume: The manual addition of views to layout is easier to code (thus potentially less moving parts and bugs), but suffers from performance problems, so if you have like 50 views or more, I advise to use the header approach.

示例.基本上,活动(或片段)布局转换为这样的(不再需要 ScrollView):

Example. Basically the activity (or fragment) layout transforms to something like this (no ScrollView needed anymore):

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/my_top_layout"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"/>

然后在 onCreateView()(我将使用一个带有片段的示例)您需要添加一个标题视图,然后设置一个适配器(我假设标题资源 ID 是 header_layout):

Then in onCreateView() (I'll use an example with a fragment) you need to add a header view and then set an adapter (I assume the header resource ID is header_layout):

ListView listView = (ListView) inflater.inflate(R.layout.my_top_layout, container, false);
View header = inflater.inflate(R.layout.header_layout, null);
// Initialize your header here.
listView.addHeaderView(header, null, false);

BaseAdapter adapter = // ... Initialize your adapter.
listView.setAdapter(adapter);

// Just as a bonus - if you want to do something with your list items:
view.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    // You can just use listView instead of parent casted to ListView.
    if (position >= ((ListView) parent).getHeaderViewsCount()) {
      // Note the usage of getItemAtPosition() instead of adapter's getItem() because
      // the latter does not take into account the header (which has position 0).
      Object obj = parent.getItemAtPosition(position);
      // Do something with your object.
    }
  }
});

这篇关于使用 ListAdapter 在 ScrollView 布局内填充 LinearLayout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆