2

我已经完成了关于这件事的所有研究。我知道 Google 认为这毫无意义,而开发人员知道事实并非如此。我也知道没有已知的解决方法,但我知道我已经接近了。用户 DougW 发布了以下代码:

public class Utility {
    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter(); 
        if (listAdapter == null) {
            // pre-condition
            return;
        }

        int totalHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
    }
}

这几乎可以为我完成工作。但是当我尝试它时,我在 listItem.measure(0, 0) 行得到一个 NullPointer 异常。listItem 本身已初始化,但该方法无论如何都会引发异常。请告诉我如何解决这个问题。

这是我的代码:

public class ExpenseReportsActivity extends Activity {

    private ListView lvReports;
    private ExpenseReportListAdapter adapter;
    private Button btnSend;
    private Button btnCancel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.expensereports);

        lvReports = (ListView)findViewById(R.id.lv_reports);
        lvReports.setBackgroundResource(R.drawable.shape_expense_report_list);

        ColorDrawable cd = new ColorDrawable(0xFFffffff);
        lvReports.setDivider(cd);
        lvReports.setDividerHeight(1);

        adapter = new ExpenseReportListAdapter(this);
        lvReports.setAdapter(adapter);

        int totalHeight = 0;
        for (int i = 0; i < adapter.getCount(); i++) {
            View listItem = adapter.getView(i, null, lvReports);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = lvReports.getLayoutParams();
        params.height = totalHeight + (lvReports.getDividerHeight() * (adapter.getCount() - 1));
        lvReports.setLayoutParams(params);
    }
}

我正在研究的另一个解决方法是使用我的自定义视图的 onWindowFocusChanged 方法。它告诉了视图的确切高度。问题是当我仍然在我的 Activiy 的 onCreate 方法中时,事件没有被触发,也没有在我的 Activity 的 onWindowFocusChanged 方法中。我尝试了一个自定义事件,但它从未触发(它被放置在我的自定义视图的 onWindowFocusChanged 方法中,而侦听器在我的 Activity 的 onWindowFocusChanged 方法中)。

4

2 回答 2

9

好的,就我得到您的需求而言,我认为您可以使用以下ListView.addFooterView(View v)方法:

http://developer.android.com/reference/android/widget/ListView.html#addFooterView(android.view.View)

它将允许您将所有列表项+“几个按钮”页脚作为一个块滚动。

所以代码应该是这样的:

import android.os.Bundle;
import android.view.LayoutInflater;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;

public class YourActivity extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LayoutInflater factory = getLayoutInflater();
        LinearLayout footer = 
            (LinearLayout) factory.inflate(R.layout.your_a_few_buttons_footer, null);

        getListView().addFooterView(footer);

        String[] array = new String[50];
        for (int i = 0; i < 50;) { array[i] = "LoremIpsum " + (++i); }

        setListAdapter(
            new ArrayAdapter<String>(this, R.layout.list_item, array)
        );
    }   
}

请注意,文档说addFooterView()应该在setListAdapter().

更新View:在列表顶部添加一个使用ListView.addHeaderView(View v). 请注意,例如,LinearLayout也是一个View. 所以你可以把任何你想要的东西作为页眉或页脚,它会作为一个不可分割的块与列表一起滚动。

于 2010-11-06T21:59:42.717 回答
1

出于好奇,您的布局是否使用RelativeLayout?如果是这样,调用measure(0,0)将始终抛出 NPE,但 LinearLayout 不会。 http://groups.google.com/group/android-developers/browse_thread/thread/5a947482d7dcb605

将其更改为线性,您可以拨打电话。我希望这会有所帮助!


我的应用程序中有一段文本、图像视图、关于给定主题的各种信息……然后,根据项目的不同,在所有这些内容的中间可能有一个比较数据的 ListView信息。大约每 10 个项目中就有一个,位于所有文本之间。比较数据最多不超过 4 个项目,所以我不希望ListView 滚动。我只希望 ListView 在我指定的确切位置完整显示。

将它们全部添加为嵌套的线性布局是很疯狂的,所以当我在屏幕上什至可能没有 ListView 时,使用 MergeAdapter 将所有这些放在一起。并且使用复杂的 ListView 页眉和页脚也是不可能的。

我不是第一个想要这种功能的人,也不会是最后一个。上面的解决方案几乎是完美的,它调整了我的 ListView 的大小,使其全屏显示,并且所有滚动都来自 ScrollView 父级。(顺便说一句,在 iOS SDK 上做这件事很容易,而且那里的很多应用程序都做类似的事情;我们需要一个好的解决方案。)

于 2010-11-09T06:29:22.873 回答